2015-03-03 169 views
0

如果我有一個集合,如下所示:MongoDB的聚集投影

db.cafe.insert({name: "Cafe1", customers: [{name: "David", foods: [{name : "cheese"}, {name: "beef"}]}, {name: "Bill", foods: [{name: "fish"}]} ]}) 


    db.cafe.find().pretty() 
{ 
    "_id" : ObjectId("54f5ae58baed23b7a34fccb6"), 
    "name" : "Cafe1", 
    "customers" : [ 
     { 
      "name" : "David", 
      "foods" : [ 
       { 
        "name" : "cheese" 
       }, 
       { 
        "name" : "beef" 
       } 
      ] 
     }, 
     { 
      "name" : "Bill", 
      "foods" : [ 
       { 
        "name" : "fish" 
       } 
      ] 
     } 
    ] 
} 

我如何可以提取只包含人稱爲「萬人迷」的食物對象的數組。 所需的輸出僅僅是食物的陣列,即:

[{name: "cheese"}, {name: "beef"}] 

我試圖聚集流水線解開網吧客戶,然後在名稱匹配,那麼項目的食品,如:

db.cafe.aggregate([{$unwind : "$customers"}, {$match : {"customers.name": "David"}}, {$project : {"customers.foods": 1, _id : 0} 

}]).pretty() 
{ 
    "customers" : { 
     "foods" : [ 
      { 
       "name" : "cheese" 
      }, 
      { 
       "name" : "beef" 
      } 
     ] 
    } 
} 

這似乎接近理想的結果,但是,我留下的問題是,我想要的食物被稱爲屬性customers.foods下的數組。我想直接得到的結果是:

[ 
      { 
       "name" : "cheese" 
      }, 
      { 
       "name" : "beef" 
      } 
     ] 

有沒有一種方法可以實現所需的輸出?

+0

我認爲你應該改變你的項目如下 '{「$ project」:{「_ id」:0,「food」:「$ customers.foods」}}' – Yogesh 2015-03-03 13:12:24

回答

2

你正在做你的投影錯誤。

db.cafe.aggregate([ 
    { "$match" : { "customers.name": "David" }}, 
    { "$unwind" : "$customers" }, 

    { "$project" : { "foods": "$customers.foods", "_id": 0 }} 
]) 

輸出

{ "foods" : [ { "name" : "cheese" }, { "name" : "beef" } ] } 
+0

謝謝,這很接近但不完全是什麼我在之後。我得到的麻煩是在我的服務器端代碼中,我正在使用Object Mapper將bson轉換爲Java對象。我試圖避免創建另一個專用於此結果集的對象並重用現有的對象。但它似乎不可能。不過謝謝你的建議,它確實很接近。 – 2015-03-04 09:22:07

1

您還可以得到(東西非常非常接近)與常規查詢您所需的輸出:

> db.cafe.find({ "customers.name" : "David" }, { "customers.$.foods" : 1, "_id" : 0 }) 
{ "customers" : [ { "name" : "David", "foods" : [ { "name" : "cheese" }, { "name" : "beef" } ] } ] } 

客戶將是包含name : "David"的第一個對象的數組。您應該更喜歡這種聚合方法,因爲它性能更高。您可以在客戶端代碼中提取foods數組。

+0

那麼,如果實際上並沒有按照要求選擇該領域,那麼注意到「客戶,食品」這一點會有什麼意義呢?這就像是說「不要打擾投射領域,因爲你可以在客戶代碼中刪除你不想要的領域」。我不明白這是如何提供任何價值的。 – 2015-03-04 00:34:24

+0

謝謝。我認爲對於我的實際用例,我將需要聚合管道(因爲我正在過濾一個數組,其中包含各種標準以及應用排序和限制),因爲它並不像這個問題所指出的那樣直截了當。我正在使用我正面臨的問題的簡化版本。 – 2015-03-04 09:24:22