76

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

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

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

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

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

更新:上面的查询确实有效。正如很多次发生的那样,我的数据是错误的,而不是我的代码。

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

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

反正有没有用基本的操作符来完成这个?

4

2 回答 2

81

使用$nin将起作用,但您的语法错误。它应该是:

db.collection.find({'docs.foo': {$nin: [1]}})
于 2013-04-25T18:22:49.440 回答
43

使用$ne运算符:

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

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

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

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

于 2016-07-31T13:53:53.000 回答