1

I'm trying to write a "startsWith" query in Spring Data, using MongoDB. If I write this in Mongo shell, it works, lists every e-mail address starting with letter x or X (case insensitive): db.user.find({email:/^x/i})

However, this doesn't:

@Query(value = "{'$or':[{'name':?0},{'email':?0}]}")
List<User> findAllByFreeTextSearch(String keyword);

I tried to add the /^.../i to the keyword itself, and in a dozen combinations to the @Query but without luck. What is the correct syntax?

Peter
  • 323
  • 1
  • 16
  • 46

2 Answers2

4

/expression/ is alternative syntax used in shell & js drivers.

You need to pass "^x" as keyword for java driver.

Try

@Query(value = "{$or:[{name:{$regex:?0,$options:'i'}},{email:{$regex:?0,$options:'i'}}]}")
List<User> findAllByFreeTextSearch(String keyword);
s7vr
  • 73,656
  • 11
  • 106
  • 127
  • Thank you, I didn't know about the / sign's purpose. I'll award you the bounty as soon as the system allows! – Peter Dec 21 '18 at 22:09
  • How is this still a regular expression search? – Asya Kamsky Dec 24 '18 at 18:57
  • @AsyaKamsky My main point was to pass the regular expression as string without the / syntax but you are correct. I copied paste the query in the question. Updated answer. – s7vr Dec 24 '18 at 19:51
2

Spring Data wraps those parameters by intent to prevent malicious patterns from being executed via an annotated query.

Please use $regex like below for that.

@Query("{'$or':[{ 'name' : { '$regex' : '?0', '$options' : 'i'}}, ...")
List<User> findAllByFreeTextSearch(String keyword);
Christoph Strobl
  • 6,491
  • 25
  • 33
  • The keyword variable should be concatenated like "/^" + keyword + "/"? Because it's not working. :/ – Peter Dec 19 '18 at 14:30
  • 1
    You don't want to use slashes - they are special syntax to designate regular expression. If you have regular expression as a *string* then you should use `{"$regex":"^x", "$options":"i"}` syntax. – Asya Kamsky Dec 24 '18 at 18:58