如何从其他集合和查询中填充引用的文档?

时间:2015-05-23 06:59:23

标签: node.js mongodb mongoose

以下是查询的示例集合,我想要的结果如下所示。如何使用mongo / nodejs查询在issuedDevices集合文档中显示设备和用户详细信息的详细信息,请帮助:

1。收集用户

/* 0 */
{
    "_id" : 1,
    "name" : "Pradeep",
    "email" : "abc@gmail.com",
    "createDate" : ISODate("2015-05-23T00:03:32.350-06:30")
}

/* 1 */
{
    "_id" : 2,
    "name" : "Steve",
    "email" : "xyz@gmail.com",
    "createDate" : ISODate("2015-05-23T00:04:02.362-06:30")
}

/* 2 */
{
    "_id" : 3,
    "name" : "Jonhy",
    "email" : "xyz123@gmail.com",
    "createDate" : ISODate("2015-05-23T00:04:30.834-06:30")
}

/* 3 */
{
    "_id" : 4,
    "name" : "Pinty",
    "email" : "p123@gmail.com",
    "createDate" : ISODate("2015-05-23T00:05:11.035-06:30")
}

2。收集设备:

/* 0 */
{
    "_id" : 1,
    "name" : "iPad",
    "owner" : "james"
}

/* 1 */
{
    "_id" : 2,
    "name" : "iPhone",
    "owner" : "Micheal"
}

第3。 collectionprovices:

 /* 0 */
    {
        "_id" : ObjectId("55602058a64447a5071a9a85"),
        "userId" : 1,
        "deviceId" : 1,
        "isReturnd" : false,
        "issuedDateTime" : ISODate("2015-05-23T00:08:16.354-06:30")
    }

/* 1 */
{
    "_id" : ObjectId("55602065a64447a5071a9a86"),
    "userId" : 2,
    "deviceId" : 1,
    "isReturnd" : true,
    "issuedDateTime" : ISODate("2015-05-23T00:08:29.355-06:30")
}

/* 2 */
{
    "_id" : ObjectId("5560207da64447a5071a9a87"),
    "userId" : 3,
    "deviceId" : 1,
    "isReturnd" : true,
    "issuedDateTime" : ISODate("2015-05-23T00:08:53.615-06:30")
}

我想要如下所示的结果,如何使用mongo / nodejs查询在issuedDevices集合的文档中显示设备和用户详细信息的详细信息。

预期输出

 [
     {
        "_id" : ObjectId("5560207da64447a5071a9a87"),
        "userId" : 3,
        "deviceId" : 1,
        "userDetails":{
            "_id" : 3,
            "name" : "Jonhy",
            "email" : "xyz123@gmail.com",
            "createDate" : ISODate("2015-05-23T00:04:30.834-06:30")
        }
        "deviceDetails":{
            "_id" : 2,
            "name" : "iPhone",
            "owner" : "Micheal"
        },
        "isReturnd" : true,
        "issuedDateTime" : ISODate("2015-05-23T00:08:53.615-06:30")
    }
]

1 个答案:

答案 0 :(得分:1)

将产生所需结果的mongodb查询将使用db.issuedDevicesforEach()光标的find()方法迭代文档并创建一个新文档,其结果为然后保存到同一个集合。以下内容为id为3的用户演示了这一点:

db.issuedDevices.find({"userId" : 3}).forEach(function (doc){
      var userDetails = db.user.findOne({"_id": 3});
      var deviceDetails = db.devices.findOne({"_id": doc.deviceId});
      doc.userDetails = userDetails;
      doc.deviceDetails = deviceDetails;
      db.issuedDevices.save(doc);
})

查询issuedDevices集合db.issuedDevices.find({"userId" : 3})将产生:

/* 0 */
{
    "_id" : ObjectId("5560207da64447a5071a9a87"),
    "userId" : 3,
    "deviceId" : 1,
    "isReturnd" : true,
    "issuedDateTime" : ISODate("2015-05-23T06:38:53.615Z"),
    "userDetails" : {
        "_id" : 3,
        "name" : "Jonhy",
        "email" : "xyz123@gmail.com",
        "createDate" : ISODate("2015-05-23T06:34:30.834Z")
    },
    "deviceDetails" : {
        "_id" : 1,
        "name" : "iPad",
        "owner" : "james"
    }
}

在Mongoose中,这可以通过在IssuedDevice模型中进行嵌套调用来完成,但是使用lean()作为从启用了lean选项的查询返回的文档是可以操作的普通javascript对象,而不是MongooseDocuments:

IssuedDevice.findOne({"userId" : 3}).lean().exec(function (err, doc) {
    User.findOne({"_id": 3}).exec(function (err, user) {
        Devices.findOne({"_id": doc.deviceId}).exec(function (err, device) {
            doc.userDetails = user;
            doc.deviceDetails = device;
            console.log(doc); // <--- gives you the result
        });
    });          
});