2016-04-07 31 views
0

任何人都可以告訴我如何將$ match階段添加到聚合管道以過濾字段匹配查詢的位置(並且可能有其他數據也在其中),而不是將結果限制到字段等於查詢的條目?

查詢規範...

var query = {hello:"world"}; 

...可以用來檢索使用MongoDB的本地節點的驅動程序,在查詢「地圖」被解釋爲一個的查找()操作下列文件比賽...

{hello:"world"} 
{hello:"world", extra:"data"} 

...喜歡...

collection.find(query); 

同樣的查詢圖也可以interprete d與$ elemMatch用於檢索與包含在象上述文件陣列匹配的條目的文件時的匹配...

​​

...使用如[PIPELINE1]調用...

collection.aggregate([ 
    {$match:{greetings:{$elemMatch:query}}}, 
]).toArray() 

然而,試圖獲得匹配的問候與開卷[PIPELINE2]列表...

collection.aggregate([ 
    {$match:{greetings:{$elemMatch:query}}}, 
    {$unwind:"$greetings"}, 
]).toArray() 

...產生任何匹配項的文件裏面的所有數組條目,包括條目w^HICH不匹配(簡化的結果)...

[ 
    {greetings:{hello:"world"}}, 
    {greetings:{hello:"world", extra:"data"}}, 
    {greetings:{hello:"world"}}, 
    {greetings:{aloha:"mars"}}, 
] 

我一直在試圖添加第二個比賽階段,但我很驚訝地發現,它的結果僅限於那些問候字段等於查詢,而不是匹配查詢[PIPELINE3]的位置。

collection.aggregate([ 
    {$match:{greetings:{$elemMatch:query}}}, 
    {$unwind:"$greetings"}, 
    {$match:{greetings:query}}, 
]).toArray() 

不幸的是PIPELINE3只產生以下條目,排除匹配的Hello World入門與額外的「數據」,因爲該條目不嚴格「平等」的查詢(簡化的結果)...

[ 
    {greetings:{hello:"world"}}, 
    {greetings:{hello:"world"}}, 
] 

...這裏是我需要的結果是相當...

[ 
    {greetings:{hello:"world"}}, 
    {greetings:{hello:"world"}}, 
    {greetings:{"hello":"world","extra":"data"} 
] 

我如何可以添加第二個$匹配階段PIPELIN E2,篩選問候字段匹配查詢的位置(也可能包含其他數據),而不是將結果限制爲問候字段等於查詢的條目?

回答

0

你在結果中看到的是正確的。你的方法有點不對。如果你想你期待的結果,那麼你應該使用這種方法:每當你在MongoDB中使用aggregation

[ 
    {greetings:{hello:"world"}}, 
    {greetings:{hello:"world"}}, 
    {greetings:{"hello":"world","extra":"data"} 
] 

和:

collection.aggregate([ 
    {$match:{greetings:{$elemMatch:query}}}, 
    {$unwind:"$greetings"}, 
    {$match:{"greetings.hello":"world"}}, 
]).toArray() 

有了這個,你應該得到下面的輸出想要創建一個可以生成您期望的文檔的聚合管道,您應該始終在第一階段開始查詢。然後最終添加階段來監控後續階段的輸出。

$unwind級的輸出將是:

[{ 
    greetings:{hello:"world"} 
}, 
{ 
    greetings:{hello:"world", extra:"data"} 
}, 
{ 
    greetings:{hello:"world"} 
}, 
{ 
    greetings:{aloha:"mars"} 
}] 

現在,如果我們包括您所使用的第三個階段,那麼這將符合該有一個值{hello:"world"}並與精確值greetings鍵,將只能找到兩個文件。所以你只會得到:

{ "greetings" : { "hello" : "world" } } 
{ "greetings" : { "hello" : "world" } } 
+0

你已經證實了我所擔心的。如前所述,我知道最後階段被解釋爲對平等的考驗。我知道我可以手動將所有字段解壓縮爲完整的路徑和值作爲相等性測試,但這正是我不想做的事情,因爲我的「查詢」可以是任何東西。問題是,儘管最後一個匹配階段在過濾邏輯中與第一階段相同,但MongoDb需要兩種不同的查詢語法。解決方法;創建例程以將匹配查詢解壓縮爲MongoDb應該首先提供的路徑平等。 – user2257198

相關問題