MongoDB case insensitive query on text with parent

2020-02-11 03:47发布

I have a very annoying problem with a case insensitive query on mongodb.

I'm using MongoTemplate in a web application and I need to execute case insensitive queries on a collection.

with this code

Query q = new Query();
q.addCriteria(Criteria.where("myField")
.regex(Pattern.compile(fieldValue, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE))); 
return mongoTemplate.findOne(q,MyClass.class);

I create the following query

{ "myField" : { "$regex" : "field value" , "$options" : "iu"}}

that works perfectly when I have simple text, for example:

caPITella CapitatA

but...but...when there are parenthesis () the query doesn't work. It doesn't work at all, even the query text is wrote as is wrote in the document...Example:

query 1:

{"myField" : "Ceratonereis (Composetia) costae" } -> 1 result (ok)

query 2:

{ "myField" : { 
    "$regex" : "Ceratonereis (Composetia) costae" , 
   "$options" : "iu"
}} -> no results (not ok)

query 3:

{ "scientificName" : { 
    "$regex" : "ceratonereis (composetia) costae" ,
    "$options" : "iu"
}}  -> no results (....)

So...I'm doing something wrong? I forgot some Pattern.SOME to include in the Pattern.compile()? Any solution?

Thanks

------ UPDATE ------

The answer of user3561036 helped me to figure how the query must be built.

So, I have resolved by modifying the query building in

q.addCriteria(Criteria.where("myField")
.regex(Pattern.compile(Pattern.quote(myFieldValue), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE))); 

The output query

{ "myField" : { "$regex" : "\\Qhaliclona (rhizoniera) sarai\\E" , "$options" : "iu"}}

works.

2条回答
淡お忘
2楼-- · 2020-02-11 04:15

Use $strcasecmp. The aggregation framework was introduced in MongoDB 2.2. You can use the string operator "$strcasecmp" to make a case-insensitive comparison between strings. It's more recommended and easier than using regex.

查看更多
家丑人穷心不美
3楼-- · 2020-02-11 04:16

If using the $regex operator with a "string" as input then you must quote literals for reserved characters such as ().

Normally that's a single \, but since it's in a string already you do it twice \\:

{ "myField" : { 
    "$regex" : "Ceratonereis \\(Composetia\\) costae" , 
    "$options" : "iu"
}}
查看更多
登录 后发表回答