mongodb - 将数组字段中的每个 ObjectId 解析为另一个集合中的对象

标签 mongodb aggregation-framework

这是一个非常具体的问题,我已经搜索堆栈溢出数小时以寻找解决方案。

我有两个集合:

事件:

{   
    _id : ObjectId,
    title : $title,
    other fields etc...,
    artist : ObjectId,
    targets : [ObjectId,ObjectId,ObjectId]
}

艺术家:

{   
    _id : ObjectId,
    name : $name,
    other fields etc...
}

每个事件都有一个包含多个目标的字段,保存为 ObjectId 的。我需要使用聚合和 $lookup 的某种组合的查询来返回一个事件(与 .find( { _id : ObjectId_of_event } ) 匹配,每个目标都解析为一个对象

它希望像这样:

{   _id : ObjectId,
    title : $title,
    other fields...,
    targets : [ {   
                   _id : ObjectId_1,
                   name : $name,
                   other fields etc...
                },
                {   
                   _id : ObjectId_2,
                   name : $name,
                   other fields etc...
                },
                {   
                   _id : ObjectId_3,
                   name : $name,
                   other fields etc...
                } ]
}

我尝试过聚合、应用 $lookup 然后在 mongodb 管道中使用 $group 但还没有找到将所有目标保留在目标中的方法数组并解析每个 ObjectId。

//编辑额外信息

我当前正在运行的查询:

db.collection("events").aggregate([
     { $match: { _id : object } }, 
     { $lookup : { 
                  from: "artists",
                  localField: "artist",
                  foreignField: "_id",
                  as: "artist_object" 
     }},
     { $unwind : "$targets"},
     { $lookup : { 
                  from: "artists",
                  localField: "targets",
                  foreignField: "_id",
                  as: "targets_objects" 
                 }} 
      }} ]).toArray(function(queryErr, main_event) etc... 

返回:

     [ { event : { _id : ObjectId,
                  title : $title,
                  artist : ObjectId,
                  targets : { artist_object_of_first_target }
                  artist_object : { artist object }
       },
       { event : { _id : ObjectId,
                  title : $title,
                  artist : ObjectId,
                  targets : { artist_object_of_second_target }
                  artist_object : { artist object }
       },
       { event : { _id : ObjectId,
                  title : $title,
                  artist : ObjectId,
                  targets : { artist_object_of_third_target }
                  artist_object : { artist object }
       }]

谁能指出我正确的方向?

最佳答案

从 mongodb 版本 3.3.4 开始,您现在可以将数组传递给 $lookup 中的 localField,在您的例子中是 targets 这样你就可以从 artists 集合中获取对象,其 _id 与目标数组中的 ObjectId 相同。此外,您首先需要通过 _id 匹配来自事件的文档。

db.collection('events').aggregate([
    {$match: {
        _id: ObjectId("58d7deaf20362d084071ea0e")
    }},
    {$lookup: {
        from: 'artists',
        localField: 'targets',
        foreignField: '_id',
        as: 'targets'
    }}
    ]).toArray().then(result => {
        console.log(JSON.stringify(result, 0, 4))
    })

另外不要忘记从 mongodb 获取 ObjectId 以便您可以在查询中使用它。

const mongodb = require('mongodb');
var ObjectId = mongodb.ObjectId;

最终结果将如下所示。

[{
  "_id": "58d7deaf20362d084071ea0e",
  "title": "Event 1",
  "targets": [{
    "_id": "58d7ded4785cdf10a8847f78",
    "name": "Artist 1"
  }, {
    "_id": "58d7dedf8f37180f0ce1db38",
    "name": "Artist 4"
  }]
}]

关于mongodb - 将数组字段中的每个 ObjectId 解析为另一个集合中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43030641/

相关文章:

Mongodb聚合管道如何限制组推送

MongoDB聚合复杂对象而不破坏其结构

python - 如何将 MongoDB 与 Keras 的 Sequence 类或生成器一起使用?

javascript - 是否有 Mongoose 方法来保存多个文档,但只有当全部成功时

node.js - mongodb TypeError : db. 集合不是函数

arrays - 如何在mongodb中删除数组的第n个元素

python - MongoDB优化FindAndModify或查找+排序

MongoDb:根据条件将元素的属性投影到文档中的数组中

mongodb - 如何使用MongoDB聚合将一串键值对转换为文档

mongodb - 如何在 mongodb shell 中使用 for 循环?