2016-07-22 55 views
1

比方說,我有兩個MongoDB的集合(以實例字段):的MongoDB:鳥巢一個集合在另一個查詢的文檔的結果

People: 
_id: 2 
name: 'bob' 
carIds: [1,2,3] 

Cars: 
_id: 82 
model: 'Camry' 

有沒有辦法返回一個列表People與一個新字段Cars,其中將有一個Cars數組carId匹配carIds人。

我不想永久創建該字段,只是爲了查詢結果。我能以某種方式用地圖來做到這一點嗎?我想:

var peopleWithCars = db.people.find({ 
}).map(function(doc) { 

    var carIds = doc.carIds; 

    var cars = db.cars.find({ 
     _id: { $in: carIds} 
    }) 

    doc.cars= cars; 

    return doc; 
}); 

return peopleWithCars ; 

,並得到:

Error: Line 18: Illegal return statement

編輯 - 這是最後的工作:

db.people.find({ 
     }).map(function(doc) { 

     var carIds = doc.carIds; 

     var cars = db.cars.find({ 
      _id: { $in: carIds} 
     }).toArray(); 

     doc.cars= cars; 

     return doc; 
    }); 

出於某種原因,它仍然不喜歡瓦爾,但是這迫使項目返回,而不是查詢它們。

回答

3

find()方法返回一個遊標。您需要將其轉換爲數組(cursor.toArray()IIRC)。這應該可以解決你的問題。

var cars= db.find(...).toArray() 

但說實話,如果你想經常使用這個查詢,那不是最好的設計。您最好在汽車中添加一個字段'personId',並使用單個查詢查詢汽車集合。

+0

更新 - 我試過了。它仍然返回與第一個版本相同的錯誤。使用第二個版本(沒有'var cars'),它返回'查詢成功執行,但是沒有結果顯示' – VSO

+1

也爲汽車領域做一個.toArray()。 – greyfairer

+0

toArray是什麼解決它,但由於某種原因,它不起作用,如果我們運行它的人發現。但它確實迫使汽車查詢執行。 Ty再次尋求幫助。 – VSO

0

您可以使用單個查詢採取的一種方法是使用聚合框架並運行具有運算符的管道。這會對同一個數據庫中的未加註集合執行左外部聯接,以過濾「已加入」集合中的文檔進行處理。 $lookup階段在來自輸入文檔的字段與來自「已加入」集合的文檔的字段之間進行平等匹配。

下面的例子演示瞭如何你可以與你的情況下將此:既然你更新

db.people.aggregate([ 
    { "$unwind": "$carIds" }, 
    { 
     "$lookup": { 
      from: "cars", 
      localField: "carIds", 
      foreignField: "_id", 
      as: "cars" 
     } 
    }, 
    { "$unwind": "$cars" }, 
    { 
     "$group": { 
      "_id": "$_id", 
      "name": { "$first": "$name" }, 
      "cars": { "$push": "$cars" } 
     } 
    } 
]) 
相關問題