检查字段是否包含字符串

joh*_*nny 404 mongodb

我正在寻找一个运算符,它允许我检查一个字段的值是否包含某个字符串.

就像是:

db.users.findOne({$contains:{"username":"son"}})
Run Code Online (Sandbox Code Playgroud)

那可能吗?

Par*_*ade 624

您可以使用以下代码执行此操作.

db.users.findOne({"username" : {$regex : ".*son.*"}});
Run Code Online (Sandbox Code Playgroud)

  • 这不是一种矫枉过正吗?你想要的是``db.users.findOne({"username":{$ regex:"son"}});`` (91认同)
  • 请注意,这不会**有效地使用索引并导致扫描所有值以进行匹配.请参阅[正则表达式]上的说明(http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions) (13认同)
  • @Stennie,那么你建议如何有效地使用索引并查找子字符串. (7认同)
  • @Vish:如果您的常见用例是字段的自由文本搜索并且您有大量文档,我会将文本标记为更有效的查询.你可以使用[multikeys](http://www.mongodb.org/display/DOCS/Full+Text+Search+in+Mongo)进行简单的全文搜索,或者建立一个[倒排索引](http: //en.wikipedia.org/wiki/Inverted_index)作为单独的集合.对于不频繁的搜索或少量文档,扫描完整索引可能是可接受的(尽管不是最佳的)性能. (4认同)
  • 可能想在Mongo 2.6中查看全文搜索 (3认同)

Jam*_*Gan 170

由于Mongo shell支持正则表达式,这是完全可能的.

db.users.findOne({"username" : /.*son.*/});
Run Code Online (Sandbox Code Playgroud)

如果我们希望查询不区分大小写,我们可以使用"i"选项,如下所示:

db.users.findOne({"username" : /.*son.*/i});
Run Code Online (Sandbox Code Playgroud)

请参阅:http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions

  • 就像所选答案中的评论一样,我相信`db.users.findOne({"username":/.*son.*/});`也可能是矫枉过正的,而正则表达式可能很简单就是`/ son /` (5认同)
  • 如果“儿子”是可变的,就像我猜的大多数用例一样 (4认同)
  • 编辑它以仅使用`{username:/ son /}` (3认同)
  • 比使用 $regex 更简洁的方式 (2认同)

Zhe*_*Kai 133

https://docs.mongodb.com/manual/reference/sql-comparison/

http://php.net/manual/en/mongo.sqltomongo.php

MySQL的

SELECT * FROM users WHERE username LIKE "%Son%"
Run Code Online (Sandbox Code Playgroud)

MongoDB的

db.users.find({username:/Son/})
Run Code Online (Sandbox Code Playgroud)

  • @maerics个人我发现郑的包含MySQL非常有用,因为它提供了一个反驳点. (88认同)
  • 我也发现SQL引用相关,我认为它应该留下来. (42认同)
  • 删除所有查询或更改它?最熟悉的SQL,它有助于理解MongoDB (26认同)
  • 你的MongoDB答案很好; 考虑编辑您的问题以删除不相关的MySQL建议. (8认同)
  • @ZhengKai:在这个网站上,您通常应该只使用标记和请求的特定技术直接回答问题. (3认同)
  • 的确。SQL 示例只是两行文本。有些人可能更愿意忽略它,而其他人可能会从中受益,而第一组的成本可能远远超过第二组的收益。 (2认同)

oko*_*oko 68

从版本2.4开始,您可以在字段上创建文本索引以搜索并使用$ text运算符进行查询.

首先,创建索引:

db.users.createIndex( { "username": "text" } )

然后,搜索:

db.users.find( { $text: { $search: "son" } } )

基准(约150K文件):

  • 正则表达式(其他答案)=> 5.6-6.9秒
  • 文本搜索=> .164-.201秒

笔记:

  • 集合只能有一个文本索引.如果要搜索任何字符串字段,可以使用通配符文本索引,如下所示:db.collection.createIndex( { "$**": "text" } ).
  • 文本索引可能很大.它为每个插入的文档的每个索引字段中的每个唯一的后梗词包含一个索引条目.
  • 构建文本索引所需的时间比正常索引要长.
  • 文本索引不存储关于文档中单词的接近度的短语或信息.因此,当整个集合适合RAM时,短语查询将更有效地运行.

  • 不,实际上文本运算符不允许执行"contains",因此它只返回精确的单词匹配,目前3.0的唯一选项是使用正则表达式,即db.users.find({username:/ son/i} )这个查找每个用户包含"儿子"(不区分大小写) (13认同)
  • 向集合中添加文档或从集合中删除文档时,是否需要重新编制索引? (3认同)

Nit*_*tai 26

由于这是搜索引擎中的第一个命中之一,并且上述所有内容似乎都不适用于MongoDB 3.x,这里有一个正常运行的正则表达式搜索:

db.users.find( { 'name' : { '$regex' : yourvalue, '$options' : 'i' } } )
Run Code Online (Sandbox Code Playgroud)

无需创建和额外索引或类似.

  • 正则表达式需要清理。 (2认同)
  • 来自谷歌,这是唯一适合我的。从文档中,选项“i”用于“不区分大小写以匹配大小写”。 (2认同)

Anu*_*sra 16

完成此任务的最简单方法

如果您希望查询区分大小写

db.getCollection("users").find({'username':/Son/})
Run Code Online (Sandbox Code Playgroud)

如果您希望查询不区分大小写

db.getCollection("users").find({'username':/Son/i})
Run Code Online (Sandbox Code Playgroud)


Pat*_*bug 15

如果您通过Python连接MongoDB,则需要执行以下操作

db.users.find({"username": {'$regex' : '.*' + 'Son' + '.*'}})
Run Code Online (Sandbox Code Playgroud)

您也可以使用变量名而不是'Son',因此也可以使用字符串连接.


小智 11

我使用这段代码,它适用于搜索子字符串

db.users.find({key: { $regex: new RegExp(value, 'i')}})
Run Code Online (Sandbox Code Playgroud)


bel*_*ola 9

如果您需要搜索多个属性,可以使用 $or。例如

Symbol.find(
  {
    $or: [
      { 'symbol': { '$regex': input, '$options': 'i' } },
      { 'name': { '$regex': input, '$options': 'i' } }
    ]
  }
).then((data) => {
  console.log(data)
}).catch((err) => {
  console.log(err)
})
Run Code Online (Sandbox Code Playgroud)

在这里,您的搜索基于输入是否包含在符号属性或名称属性中。


Kus*_*eth 8

如果正则表达式在您的聚合解决方案中不起作用并且您有嵌套对象。尝试这个聚合管道:(如果您的对象结构很简单,只需从下面的查询中删除其他条件):

db.user.aggregate({$match: 
     {$and:[
   {"UserObject.Personal.Status":"ACTV"},
   {"UserObject.Personal.Address.Home.Type":"HME"},
   {"UserObject.Personal.Address.Home.Value": /.*son.*/ }
   ]}}
   ) 
Run Code Online (Sandbox Code Playgroud)

另一种方法是直接查询,如下所示:

db.user.findOne({"UserObject.Personal.Address.Home.Value": /.*son.*/ });
Run Code Online (Sandbox Code Playgroud)


His*_*ham 7

理想答案它的使用索引 i选项不区分大小写

db.users.findOne({"username" : new RegExp(search_value, 'i') });
Run Code Online (Sandbox Code Playgroud)

  • 正则表达式需要清理。 (2认同)

小智 7

这应该做的工作

db.users.find({ username: { $in: [ /son/i ] } });
Run Code Online (Sandbox Code Playgroud)

i是只是为了防止匹配的字母单例的限制。

您可以查看$regex有关 MongoDB 文档的文档。这是一个链接:https : //docs.mongodb.com/manual/reference/operator/query/regex/


Sco*_*ger 6

如果您的正则表达式包含变量,请确保对其进行转义

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
Run Code Online (Sandbox Code Playgroud)

可以像这样使用

new RegExp(escapeRegExp(searchString), 'i')
Run Code Online (Sandbox Code Playgroud)

或者在像这样的 mongoDb 查询中

{ '$regex': escapeRegExp(searchString) }
Run Code Online (Sandbox Code Playgroud)

在这里发表了相同的评论


F.H*_*.H. 6

对于聚合框架


实地搜寻

'$options': 'i'用于不区分大小写的搜索)

db.users.aggregate([
    {
        $match: {
            'email': { '$regex': '@gmail.com', '$options': 'i' }
        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

完整文档搜索

(仅适用于使用文本索引索引的字段

db.articles.aggregate([
    {
        $match: { $text: { $search: 'brave new world' } }
    }
])
Run Code Online (Sandbox Code Playgroud)