在 MongoDB 中查找数组中不包含具有特定字段值的文档的文档

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16221599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 13:10:30  来源:igfitidea点击:

Find documents with arrays not containing a document with a particular field value in MongoDB

mongodb

提问by Scott

I'm trying to find all documents that do not contain at least one document with a specific field value. For example here is a sample collection:

我正在尝试查找不包含至少一个具有特定字段值的文档的所有文档。例如,这是一个示例集合:

{  _id : 1,
  docs : [
        { foo : 1,
          bar : 2},
        { foo : 3,
          bar : 3}
         ]
},
{  _id : 2,
  docs : [
        { foo : 2,
          bar : 2},
        { foo : 3,
          bar : 3}
         ]
}

I want to find every record where there is not a document in the docs block that does not contain at least one record with foo = 1. In the example above, only the second document should be returned.

我想找到每条记录,其中 docs 块中没有包含至少一个 foo = 1 记录的文档。在上面的示例中,只应返回第二个文档。

I have tried the following, but it only tells me if there are any that don't match (which returns document 1.

我尝试了以下操作,但它只告诉我是否有任何不匹配的(返回文档 1.

db.collection.find({"docs": { $not: {$elemMatch: {foo: 1 } } } })

UPDATE:The query above actually does work. As many times happens, my data was wrong, not my code.

更新:上面的查询确实有效。很多时候,我的数据是错误的,而不是我的代码。

I have also looked at the $nin operatorbut the examples only show when the array contains a list of primitive values, not an additional document. When I've tried to do this with something like the following, it looks for the EXACT document rather than just the foo field I want.

我还查看了$nin 运算符,但示例仅显示数组何时包含原始值列表,而不是附加文档。当我尝试使用以下内容执行此操作时,它会查找 EXACT 文档,而不仅仅是我想要的 foo 字段。

db.collection.find({"docs": { $nin: {'foo':1 } } })

Is there anyway to accomplish this with the basic operators?

有没有办法用基本的操作符来完成这个?

回答by JohnnyHK

Using $ninwill work, but you have the syntax wrong. It should be:

使用$nin将工作,但你有语法错误。它应该是:

db.collection.find({'docs.foo': {$nin: [1]}})

回答by aedm

Use the $neoperator:

使用$ne运算符:

db.collection.find({'docs.foo': {$ne: 1}})

Update:I'd advise against using $ninin this case.

更新:我建议不要$nin在这种情况下使用。

{'docs.foo': {$ne: 1}}takes all elements of docs, and for each of them it checks whether the foofield equals 1 or not. If it finds a match, it discards the document from the result list.

{'docs.foo': {$ne: 1}}获取 的所有元素docs,并针对每个元素检查该foo字段是否等于 1。如果找到匹配项,则从结果列表中丢弃该文档。

{'docs.foo': {$nin: [1]}}takes all elements of docs, and for each element it checks whether its foofield matches any of the members of the array [1]. This is a Cartesian product, you compare an array to another array, each element to each element. Although MongoDB might be smart and optimize this query, I assume you only use $ninbecause "it has do to something with arrays". But if you understand what you do here, you'll realize $ninis superfluous, and has possibly subpar performance.

{'docs.foo': {$nin: [1]}}获取 的所有元素docs,并针对每个元素检查其foo字段是否与数组的任何成员匹配[1]。这是一个笛卡尔积,您将一个数组与另一个数组进行比较,每个元素与每个元素进行比较。虽然 MongoDB 可能很聪明并优化了这个查询,但我假设你只使用$nin它是因为“它对数组有作用”。但是,如果您了解您在这里所做的事情,您就会意识到这$nin是多余的,并且性能可能低于标准。