【问题标题】:How to find a substring in a field in Mongodb如何在 Mongodb 的字段中查找子字符串
【发布时间】:2021-04-13 14:50:49
【问题描述】:

如何找到数据库中的所有对象,其中对象的字段包含子字符串?

如果该字段是具有字符串值的集合对象中的A:

我想在 db“数据库”中找到所有对象,其中 A 包含一个子字符串,比如“abc def”。

我试过了:

db.database.find({A: {$regex: '/^*(abc def)*$/''}})

但没用

更新

一个真实的字符串(unicode):

Sujet  Commentaire sur  Star Wars  Episode III - La Revanche des Sith 1

需要用星球大战搜索所有条目

db.test.find({A: {$regex: '^*(star wars)*$''}}) not wokring

【问题讨论】:

  • 正如@derick 指出的那样,如果您想查找“任何字符串”,您需要.*. 用于任何(单个)字符,* 用于“前一个任意次数(包括零)次。您拥有的(star wars)*$ 将匹配“star warsstar warsstar wars”,但不会匹配“star wars is great”。

标签: mongodb nosql


【解决方案1】:

而不是这个:

db.database.find({A: {$regex: '/^*(abc def)*$/''}})

你应该这样做:

db.database.find({A: /abc def/i })

^* 实际上不是有效的语法,因为 ^ 和 $ 是锚点,而不是可重复的东西。你可能是指 ^.* 这里。但是不需要 ^.* 因为这只是表示“直到后面的字符的所有内容”并且 (abc def)* 表示“0 次或多次“abc def”,但它必须位于字符串的末尾,因为你的$。最后的“i”是让它不区分大小写。

【讨论】:

  • 请注意,使用 '^' 有助于加快正则表达式查询,因为索引仅在这种形式下才有效(请参阅页面底部docs.mongodb.org/manual/reference/operator/regex
  • 如果我错了,请纠正我,但 '^*' 有意义吗?不应该是'^.*'吗?对我来说,'^*' 读作“行的零个或多个开头”,其中只有一个,而且总是一个,在我看来它 不允许 开头之间的字符行和正则表达式的其余部分...
  • @drevicko,你是对的。这是我的回答中的一个错字。我已经澄清了。
  • 值得注意的是,如果您在A 上有一个索引,则只有在the regex is anchored to the start of the line and is case sensitive 时才会使用它 - 即:/^.*abc def/
  • drevicko,这是不正确的。正则表达式匹配的第一部分必须是 static 否则它将不得不进行完整的集合扫描。即: ^abcdef 仅使用索引的一部分效果很好,但 ^.*abcdef 没有。在第一种情况下,首先进行范围查询 (>= "abcdef &
【解决方案2】:

只需使用字符串“星球大战”,$regex 将完成剩下的工作

db.test.find({A: {$regex: 'Star Wars'}})

【讨论】:

  • 这个很好,但是这个是区分大小写的
  • 不区分大小写:db.test.find({A: {$regex: 'Star Wars', $options: "$i"}})
【解决方案3】:

$regex 在大型收藏中太贵/太慢了。

我建议利用聚合框架和$indexOfCP

db.test.aggregate([{$match: 
    {$expr: { $gt: [{ $indexOfCP: [ "$A", "Star Wars" ] }, -1]}}
    }, {$project: {A:1}}])

对于不区分大小写的搜索,您可以添加 $toUpper 并搜索 STAR WARS

【讨论】:

    【解决方案4】:

    这对我有用:

    db.test.find({"A": {'$regex': '.*star wars.*'}})
    

    【讨论】:

      【解决方案5】:
      // executes, name LIKE john and only selecting the "name" and "friends" fields
      db.collection.find({ name: /john/i }, 'name friends').exec();
      
      // passing options
      db.collection.find({ name: /john/i }, null, { skip: 10 }).exec();
      

      【讨论】:

        【解决方案6】:

        这个使用聚合语法:

        db.movies.aggregate([
          {$match: 
            {
              title: {$regex: 'Star'}
            } 
          }
        ] )
        

        【讨论】:

          猜你喜欢
          • 2021-04-25
          • 2019-10-01
          • 2020-05-12
          • 2011-07-13
          • 2021-04-21
          • 2020-06-11
          • 1970-01-01
          相关资源
          最近更新 更多