首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有<集合的MongoDB $lookup来自输入文档的join>

带有<集合的MongoDB $lookup来自输入文档的join>
EN

Stack Overflow用户
提问于 2019-08-31 21:37:41
回答 2查看 112关注 0票数 0

这是mongodb的新手,所以这可能是一个愚蠢的问题。我使用的是MongoDB查找聚合,但“from”集合是输入文档中的一个字段。如何在“from”而不是字符串文字中指示该字段?

我开始使用的集合的简化版本("Groups")的文档如下所示:

代码语言:javascript
复制
{
   _id: "<ObjectId>",
   collectionName: "MyCollectionA",
   list: ["<Foreign ObjectId>", "<Foreign ObjectId>", "<Foreign ObjectId>"]
}

我加入了另一个收藏。在本例中,为"MyCollectionA“。

我的查找工作正常,如下所示:

代码语言:javascript
复制
{ 
   $lookup: {
      from: "MyCollectionA",  
      localField: "list",
      foreignField: "_id",
      as: "myJoinedItems"    
   }
}

但是,我希望能够在查找中使用字段'collectionName‘,而不是硬编码'MyCollectionA’。我该怎么做呢?我尝试过'$collectionName‘和{ $literal:'$collectionName },但是没有成功。

EN

回答 2

Stack Overflow用户

发布于 2019-09-02 16:17:02

下面的查询可以做到这一点。我们遍历Groups集合的每条记录,并在每个文档中为对象ID列表指定的集合上执行查找操作。因为_id上有一个默认索引,所以搜索操作会很快。

代码语言:javascript
复制
db.Groups.find().forEach(doc=>{
    var myJoinedItems = [];
    doc["list"].forEach(id=>{
        myJoinedItems.push(
            db.getCollection(doc["collectionName"]).find({"_id":id})[0]
        );
    });
    doc["myJoinedItems"]=myJoinedItems;
    print(tojson(doc));
});

输出:

代码语言:javascript
复制
{
    "_id" : ObjectId("5d6cac366bc2ad3b23f7de74"),
    "collectionName" : "MyCollectionA",
    "list" : [
        ObjectId("5d6cabd16bc2ad3b23f7de72")
    ],
    "myJoinedItems" : [
        {
            "_id" : ObjectId("5d6cabd16bc2ad3b23f7de72"),
            "collectionDetails" : {
                "name" : "MyCollectionA",
                "info" : "Cool"
            }
        }
    ]
}
{
    "_id" : ObjectId("5d6cb82a6bc2ad3b23f7de76"),
    "collectionName" : "MyCollectionB",
    "list" : [
        ObjectId("5d6cb7fd6bc2ad3b23f7de75")
    ],
    "myJoinedItems" : [
        {
            "_id" : ObjectId("5d6cb7fd6bc2ad3b23f7de75"),
            "collectionDetails" : {
                "name" : "MyCollectionB",
                "info" : "Super-Cool"
            }
        }
    ]
}

数据集:

集合:

代码语言:javascript
复制
{
    "_id" : ObjectId("5d6cac366bc2ad3b23f7de74"),
    "collectionName" : "MyCollectionA",
    "list" : [
        ObjectId("5d6cabd16bc2ad3b23f7de72")
    ]
}
{
    "_id" : ObjectId("5d6cb82a6bc2ad3b23f7de76"),
    "collectionName" : "MyCollectionB",
    "list" : [
        ObjectId("5d6cb7fd6bc2ad3b23f7de75")
    ]
}

集合: MyCollectionA

代码语言:javascript
复制
{ 
    "_id" : ObjectId("5d6cabd16bc2ad3b23f7de72"),
    "collectionDetails":{
        "name":"MyCollectionA",
        "info":"Cool"
    }
}

集合: MyCollectionB

代码语言:javascript
复制
{ 
    "_id" : ObjectId("5d6cb7fd6bc2ad3b23f7de75"),
    "collectionDetails":{
        "name":"MyCollectionB",
        "info":"Super-Cool"
    }
}
票数 0
EN

Stack Overflow用户

发布于 2019-09-03 04:21:52

下面是一个直接使用$lookup的变体。

代码语言:javascript
复制
db.foo.drop();
db.foo1.drop();
db.foo2.drop();

db.foo.insert(
[
 {_id:0, collectionName:"foo1", list: ['A','B','C'] },
 {_id:1, collectionName:"foo2", list: ['D','E'] }
]);

db.foo1.insert([
{_id:0, key:"A", foo1data:"goodbye"},
{_id:1, key:"B", foo1data:"goodbye"},
{_id:2, key:"C", foo1data:"goodbye"}
]);

db.foo2.insert([
{_id:0, key:"C", foo2data:"goodbye"},
{_id:1, key:"D", foo2data:"goodbye"}
]);

// Pass 1:  Collect unique collections.                                         
c = db.foo.distinct("collectionName");

// Pass 2:  Get 'em:                                                            
c.forEach(function(collname) {
        c2 = db.foo.aggregate([
        {$match: {"collectionName": collname}}
        ,{$lookup: {"from": collname,
                     // Clever twist: if localField is a list, then the lookup
                     // behaves like an in-list:
                     localField: "list", 
                     foreignField: "key",
                     as: "X" }}

         ]);

    });
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57738477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档