【问题标题】:MongoDB case insensitive query on text with parenthesisMongoDB对带括号的文本不区分大小写查询
【发布时间】:2015-09-05 07:02:34
【问题描述】:

我在 mongodb 上遇到了一个非常烦人的不区分大小写查询的问题。

我在 Web 应用程序中使用 MongoTemplate,我需要对集​​合执行不区分大小写的查询。

使用此代码

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);

我创建以下查询

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

当我有简单的文本时效果很好,例如:

caPITella CapitatA

但是...但是...当有 括号 () 时,查询不起作用。 根本不行,连查询文本都写成文档里写的那样……例子:

查询 1:

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

查询 2:

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

查询 3:

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

所以...我做错了什么?我忘记了要包含在 Pattern.compile() 中的 Pattern.SOME?有什么解决办法吗?

谢谢

----- 更新 ------

user3561036 的回答帮助我弄清楚了必须如何构建查询。

所以,我已经通过修改查询构建解决了

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

输出查询

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

有效。

【问题讨论】:

  • 为什么在选项中使用u("$options" : "iu")?

标签: regex mongodb mongodb-query


【解决方案1】:

如果使用$regex 运算符和“字符串”作为输入,那么您必须为保留字符引用文字,例如()

通常这是一个单一的\,但由于它已经在一个字符串中,所以你会这样做两次\\

{ "myField" : { 
    "$regex" : "Ceratonereis \\(Composetia\\) costae" , 
    "$options" : "iu"
}}

【讨论】:

  • 好,回答...它给了我解决问题的输入:'Query q = new Query(); q.addCriteria(Criteria.where("myField") .regex(Pattern.compile(Pattern.quote(myFieldValue), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE))); ' 这给了我输出查询: '{ "scientificName" : { "$regex" : "\\Qhaliclona (rhizoniera) sarai\\E" , "$options" : "iu"}}' 有效。
  • @dgiaig 好吧,它应该指出,因为这就是使用字符串编译的方式。这里的方法是矫枉过正,因为只有像 () 这样的字符被保留,正如我所说的。这是一个正则表达式问题。不要忘记accept你的答案。
  • @dgiaig 没关系,欢迎您。并欢迎堆栈溢出。正如目前您的问题的四个赞成票和两个观察者所证明的那样,这几乎是吃力不讨好的,但这里只有一票赞成票和您自己的接受(谢谢)。所以只是一个习惯的预览。
  • 当我的字符串动态出现时我该怎么做
【解决方案2】:

使用 $strcasecmp。 聚合框架是在 MongoDB 2.2 中引入的。您可以使用字符串运算符“$strcasecmp”在字符串之间进行不区分大小写的比较。 它比使用正则表达式更推荐和更容易。

【讨论】:

    【解决方案3】:

    这是一个老问题,但你可以使用query.replace(/[-[\]{}()*+?.,\\/^$|#\s]/g, "\\$&");

    这适用于 aggregatematches

     const order = user_input.replace(/[-[\]{}()*+?.,\\/^$|#\s]/g, "\\$&");
     const regex = new RegExp(order, 'i');
     const query = await this.databaseModel.aggregate([
            {
              $match: {
                name : regex
            }
        // ....
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-15
      • 2017-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      • 1970-01-01
      相关资源
      最近更新 更多