2016-03-24 106 views
1

我知道這違反了MongoDB和它的無SQL模型的設計,但我試圖在一個集合中查找文檔,然後使用結果中的ID字段進行查找在另一個集合中對應的記錄有效地嘗試模擬連接。MongoDB,從一個Mongoose結果查找搜索另一個集合

//query is irrelevant to question 
var results = collectionOne.find(query).limit(limit); 

var a = []; 

results.forEach(function(r) 
{ 
    var aquery = { id : {$eq : r.id}}; 
    collectionTwo.find(aquery).limit(limit).exec(function, b) 
    { 
     if (err) 
     { 
      res.render('error', 
      { 
       status : 500 
      }); 
     } 
     else 
     { 
      a.push(b); 
     } 
    }); 
}); 
res.jsonp(a); 
+0

你可以使用匯總和$ lookup來執行這個服務器端 – profesor79

回答

6

雖然有MongoDB中如$lookup,它做了「之類的加盟」的新功能,您的具體操作並不需要這個。你在這裏所做的就是根據_id值與前一個值匹配的位置返回另一個集合的結果。

爲此,最好的選擇是發出一個更多查詢使用$in其他集合。

// Mongoose turns a cursor to an array by default in the callback method 
collectionOne.find(query,{ "_id": 1}).limit(limit).exec(function(err,results) { 

    // Just get array of _id values 
    var ids = results.map(function(el) { return el._id }); 

    // Not sure if you really mean both collections have the same primary key 
    // I'm presuming two different fields being "id" as opposed to "_id" 
    collectionTwo.find({ "id": { "$in": ids } },function(err,items) { 
     // matching results are here 
    }) 

}) 

就是這樣。

你要做的就是返回_id值的第一個查詢結果爲的只是「表」,然後提供這樣的說法來$in在相關領域的目標集合

中如果你真的想要一個「加盟「,並有MongoDB的3.2可用,那麼你可以使用$lookup這樣

collectionOne.aggregate([ 
    { "$match": query }, 
    { "$limit": limit }, 
    { "$lookup": { 
     "from": "collectionTwo", 
     "localField": "_id", 
     "foreignField": "id", 
     "as": "twoItems" 
    }} 
]) 

這是一個真正的‘加盟’的結果,這雖然能夠可能用它剛剛從collectionTwo返回匹配結果,那麼我的人物lly不會。即使在服務器上也是昂貴的練習,並且進一步過濾實際返回該格式所需的操作最終將花費更多成本。

您也可以閱讀關於貓鼬的.populate(),這實際上是這種查詢類型的「反向」。相反,它的過程是存儲指向相關集合中對象的主鍵的數組(或本例中的常規字段)的ObjectId值。因此,如果collectionTwo有「許多」值,那麼這些值將被存儲在collectionOne文件中的數組中。

同樣,這是一個「連接仿真」,而不是一個真正的連接。結果將類似於$lookup,並且再也不是「僅僅」來自collectionTwo的結果,而是「加入」版本,您同樣需要過濾。

.populate()確實發生的一切就是它無論如何都會運行一個$in查詢。因此,即使在將子引用存儲在父級(恕我直言,在大多數情況下,如果你可以這樣做,那麼你也可以直接嵌入數據)的所有工作之後,與數據庫的實際交互保持不變,因爲它仍然執行$in查詢。

+0

@ user3424480不確定你認爲你的意思在那裏。如果你的意思是說當一個「源代碼」使用「ObjectId」時,那麼「目標」必須是這樣,當然它確實如此。這對任何BSON類型都是如此。 –

相關問題