2013-04-25 262 views
30

我試圖找到所有文檔不包含至少一個具有特定字段值的文檔。例如這裏是一個樣本收集:在MongoDB中查找包含不包含具有特定字段值的文檔的數組的文檔

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

我想找到的每個記錄那裏是不是在文檔塊的文件不包含以foo = 1的至少一個記錄在上面的例子中,只有第二份文件應該被退回。

我曾嘗試以下,但它只是告訴我,如果有任何不匹配(返回文檔1.

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

UPDATE:上面實際上做的工作,因爲許多查詢。我的數據是錯誤的,而不是我的代碼

我也看過$nin operator,但這些例子只顯示當數組包含一個原始值列表,而不是一個額外的文檔當我試圖做這與類似以下的東西,它尋找的是EXACT文件而不是ju我想要的foo領域。

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

有沒有辦法用基本操作符來完成這項工作?

回答

38

使用$nin可以工作,但是您的語法錯誤。它應該是:

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

好奇,爲什麼'$ nin'而不是'$ ne'?難道你不能'db.collection.find({'docs.foo':{$ ne:1}})'? (即同樣的事情,但不需要1在數組中,如在[aedm的回答](http://stackoverflow.com/a/38684656/3391108)) – tscizzle 2016-11-01 19:13:39

+1

@tscizzle是的,'$ ne'是好的以及如果只有一個值。 – JohnnyHK 2016-11-01 19:15:17

+0

'$ ne'也應該更有效率(更快) – ztrange 2017-03-16 00:43:52

11

使用$ne操作:

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

更新:我建議不要在這種情況下使用$nin

{'docs.foo': {$ne: 1}}docs的所有元素,並且對於其中的每個元素,它檢查foo字段是否等於1。如果找到匹配項,它將放棄結果列表中的文檔。

{'docs.foo': {$nin: [1]}}需要的docs所有元素,並且每個元素它檢查其foo字段是否匹配任何陣列[1]成員。這是一個Cartesian product,你比較一個數組與另一個數組,每個元素的每個元素。雖然MongoDB可能很聰明,並且可以優化這個查詢,但我認爲你只使用$nin,因爲「它對數組有一定的作用」。但是,如果你明白你在這裏做什麼,你會發現是多餘的,並且可能表現不佳。

相關問題