繁体   English   中英

MongoDB,Mongoose来自一个Find来搜索另一个集合

[英]MongoDB, Mongoose results from one Find to search another collection

我知道这违反了MongoDB及其No-SQL模型的设计,但我试图在一个集合中查找Documents,然后使用结果中的ID字段来查找另一个集合中的相应记录。 有效地尝试模拟联接。

//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);

虽然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 ,那么我个人不会。 即使在服务器上也是昂贵的练习,并且进一步过滤实际返回该格式所需的操作将最终花费更多。

您还可以在.populate()阅读.populate() ,这实际上是此类查询的“反向”。 相反,它的过程是存储指向相关集合中对象的主键的ObjectId值的数组(或常规字段,但在这种情况下为数组)。 因此,如果collectionTwo有“很多”值,那么这些值将存储在collectionOne文档中的数组中。

同样,这是一个“加入模拟”而不是真正的连接。 结果类似于$lookup ,并且同样不是“just”来自collectionTwo的结果,而是“加入”版本,您同样需要过滤。

.populate()真正发生的是它无论如何都$in运行$in查询。 因此,即使在父项中存储子引用的所有工作(恕我直言,在大多数情况下,如果你可以这样做,那么你也可以只是嵌入数据),与数据库的实际交互保持不变,因为它仍然执行$in query。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM