Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb Mongo查找使用$id引用加入集合_Mongodb - Fatal编程技术网

Mongodb Mongo查找使用$id引用加入集合

Mongodb Mongo查找使用$id引用加入集合,mongodb,Mongodb,我有一个名为post的集合,它引用了另外两个集合:status和format post: { "_id" : ObjectId("5d7c1c4549c5e277395871ad"), "status" : { "$ref" : "status", "$id" : ObjectId("status123") }, "format" : { "$ref" : "format", "$id" : Obje

我有一个名为post的集合,它引用了另外两个集合:status和format

post:
{
    "_id" : ObjectId("5d7c1c4549c5e277395871ad"),
    "status" : {
        "$ref" : "status",
        "$id" : ObjectId("status123")
    },
    "format" : {
        "$ref" : "format",
        "$id" : ObjectId("format123")
    }
}

status:
{
    "_id" : ObjectId("status123"),
    "name" : "Draft"
}

format:
{
    "_id" : ObjectId("format123"),
    "name" : "Standard"
}
我希望post查询返回以下内容:

post:
{
    "_id" : ObjectId("5d7c1c4549c5e277395871ad"),
    "status" : {
        "_id" : ObjectId("status123"),
        "name" : "Draft"
    },
    "format" : {
        "_id" : ObjectId("format123"),
        "name" : "Standard"
    }
}
我的Mongo查询应该是什么?我是刚使用MongoDB的,非常感谢您的帮助

谢谢,
很遗憾,您不能在字段名中使用
$
。 但如果我们用这个来代替:

var sid1 = new ObjectId();
var fid1 = new ObjectId();

var postdoc =
{
    "_id" : ObjectId("5d7c1c4549c5e277395871ad"),
    "status" : {
        "ref" : "status",
        "id" : sid1
    },
    "format" : {
        "ref" : "format",
        "id" : fid1
    }
};

var statusdoc =
{
    "_id" : sid1,
    "name" : "Draft"
};

var formatdoc =
{
    "_id" : fid1,
    "name" : "Standard"
};

db.post.insert(postdoc);
db.status.insert(statusdoc);
db.format.insert(formatdoc);

然后这个查询:

db.post.aggregate([
{$lookup: {"from": "status",
                     localField: "status.id",
                     foreignField: "_id",
                     as: "STATUS" }}

,{$lookup: {"from": "format",
                     localField: "format.id",
                     foreignField: "_id",
                     as: "FORMAT" }}

,{$project: {
        "status": {$arrayElemAt: [ "$STATUS",0 ] },
        "format": {$arrayElemAt: [ "$FORMAT",0 ] }
    }}

                      ]);
产生期望的结果:

{
    "_id" : ObjectId("5d7c1c4549c5e277395871ad"),
    "status" : {
        "_id" : ObjectId("5d7c921a32c55e3d729b552f"),
        "name" : "Draft"
    },
    "format" : {
        "_id" : ObjectId("5d7c921a32c55e3d729b5530"),
        "name" : "Standard"
    }
}

回答你的问题

你可以这样做

 db.post.aggregate([
{$project :
           { status:
                    {$arrayElemAt:
                                  [{$objectToArray:"$status"},1]
                     },
            format:
                   {$arrayElemAt:
                                  [{$objectToArray:"$format"},1]
            }}},
{$project:
          {status:"$status.v" ,
          format:"$format.v"}
},

{$lookup : 
          {from :"status" ,
           localField : "status",
            foreignField:"_id" ,
           as :"status"}
},
{$lookup:
          {from :"format" ,
          localField:"format",
          foreignField:"_id",
           as:"format"}
},
{$unwind :"$status"},
{$unwind:"$format"}
])
结果看起来像

{ "_id" : ObjectId("5d7c1c4549c5e277395871ad"),
"status" : { 
           "_id" : ObjectId("5d7c4af7c45316e35251a499"),
             "name" : "Draft" 
            },
 "format" : { 
           "_id" : ObjectId("5d7c4b21c45316e35251a49a"),
            "name" : "Standard" 
           } 
}
解释

阶段1:使用
$objectToArray
将文档转换为数组,我们使用它转换DBref
阶段2:使用
$arrayElemAt
$project
获取链接的“\u id”

阶段3:使用
$lookup
连接两个集合
阶段4:使用
$unwind
获取内部文档。从输入文档解构数组字段以输出每个元素的文档

I could get the desired output using variables.

var post = db.post.findOne({"_id":ObjectId("5d7c8fb8ba38a9196e5fc195")})
var dbRef = post.status
var status = db[dbRef.$ref].findOne({"_id":(dbRef.$id)})
var dbRef1 = post.format
var format = db[dbRef1.$ref].findOne({"_id":(dbRef1.$id)})

db.post.aggregate({ $project : { "_id" : post._id , "status" : status , "format" : format}})
您可以查看MongoDB数据库引用链接以了解更多信息。

这是对数据库的3次单独往返。为什么要使用
$objectToArray
。。。?在这种情况下有点过分了,不是吗?@HbnKing当我使用$unwind时,我看到我所有的帖子都没有返回,有些帖子在结果中显示了多次。我会把我所有的帖子都退回一次,而且只有一次。我可以删除$unwind吗?这似乎解决了我的问题?@BuzzMoschetti你说$objectToArray是什么意思?你有更好的解决方案吗??是的,昨天贴在下面。警告:我已将
状态。$id
格式。$id
更改为
状态.id
格式.id
我不确定OP是否也不能这样做,但是,在使用聚合运算符和字段路径函数时,字段名中以
$
开头的数据设计会遇到问题。请使用
$unwind
{$unwind:{path:$size',preserveNullAndEmptyArrays:true}等选项