2014-10-09 21 views
0

說我有一個文檔的集合,象下面這樣:當屬性不​​存在時選擇記錄?

{ 
    title: "test1", 
    items: 
    [ 
     {id: 1, sub_id: 23, value:"some value"}, 
     {id: 2, value:"some value"} 
    ] 
}, 
{ 
    title: "test2", 
    items: 
    [ 
     {id: 4, sub_id: 34, value:"blah"}, 
     {id: 5, sub_id: 56, value:"whatever"}, 
    ] 
} 

我想選擇其中屬性sub_id不存在與id屬性確實存在。如果我運行查詢:

db.myCollection.find({"items.sub_id": {$exists: false}}) 

返回我想要的記錄(用test1標題的文件),但是當我運行此查詢:

db.myCollection.find({"items.sub_id": {$exists: false}, "items.id": {$exists:true}}) 

它沒有返回。我的第二個查詢不應該返回與第一個查詢相同的結果

回答

1

實際上,您的第一個查詢無法返回您給出的樣本的結果。原因是這兩個文檔都沒有沒有數組元素不包含「sub_id」屬性。因此,在第一個文檔中,雖然第二個數組元素缺少該屬性,但第一個文檔確實有一個,因此該條件實際上是錯誤的。一個有趣的事情與$exists和一個虛假的測試位。

所以爲了使這項工作,你需要比較個別數組元素的條件。這意味着你需要的$elemMatch操作:

db.myCollection.find({ 
    "items": { 
     "$elemMatch": { 
      "id": { "$exists": true }, 
      "sub_id": { "$exists": false } 
     } 
    } 
}) 

這正確選擇具有地方有一個「id」屬性,但沒有「sub_id」屬性的數組元素的文檔。

由於是$exists遍歷文件相匹配的條件下,同樣也適用於一個單一的元素,以及,因此您使用$elemMatch只有單場情形之一的方式:

db.myCollection.find({ 
    "items": { 
     "$elemMatch": { 
      "sub_id": { "$exists": false } 
     } 
    } 
}) 

因此,強制測試應用於數組元素,當然一個元素沒有屬性,因此至少有一個匹配並返回文檔。