Javascript MongoDB聚合$lookup到父数组字段,管道语法和_id为字符串

Javascript MongoDB聚合$lookup到父数组字段,管道语法和_id为字符串,javascript,mongodb,mongoose,aggregation-framework,Javascript,Mongodb,Mongoose,Aggregation Framework,我的MongoDB(v.4.4)中有以下收藏: 行业协会: { _id:String, 成员:[{u id String,rank:number},{u id String,rank:number}…] } 和字符: { _id:String, 许多其他的领域 } 我想加入$lookup管道语法guild.members当您传递成员时,不需要使用管道查找。_id作为localField $lookup带有字符并传递成员。\u id作为localField $map迭代成员的循环数组 $fi

我的MongoDB(v.4.4)中有以下收藏:

行业协会

{
_id:String,
成员:[{u id String,rank:number},{u id String,rank:number}…]
}
字符

{
_id:String,
许多其他的领域
}

我想加入
$lookup
管道语法
guild.members当您传递
成员时,不需要使用管道查找。_id
作为localField

  • $lookup
    带有字符并传递
    成员。\u id
    作为localField
  • $map
    迭代
    成员的循环
    数组
  • $filter
    迭代
    成员的循环\u guid
    并获取匹配的成员
  • $arrayElemAt
    从上述过滤器中获取第一个匹配元素
  • $mergeObjects
    将当前字段与上述成员的筛选对象合并

我接受@turivishal的答案,因为老式的本机聚合比
管道
语法更容易理解。但如果有人感兴趣,我以前使用的聚合部分

db.guilds.aggregate([
{
$lookup:{
来自:“角色”,
让我们:{
成员:“$成员”
},
管道:[
{
$match:{
$expr:{
$in:[
“$\u id”,
“$$members.\u id”
]
}
}
},
{
$addFields:{
排名:{
美元减少:{
输入:“$$members”,
initialValue:null,
在:{
$cond:[
{
$eq:[
“$$this.\u id”,
“$\u id”
]
},
“$$this.rank”,
“$$value”
]
}
}
}
}
}
],
as:“成员”
},
}
])

查询很好,我还有另一个查询,问题有点大。在
$lookup
阶段之前或之后,要从合并文档(
字符
)中删除/排除哪些字段?例如(
characters.pets
)。在这种情况下,我可以在
$project
阶段,在
$map
中简单地删除它们。我在这里说的对吗?是的,你可以,但是如果你在添加额外的项目阶段删除它会更好,请参阅
db.guilds.aggregate([
  {
    $lookup: {
      from: "characters",
      localField: "members._id",
      foreignField: "_id",
      as: "members_guid"
    }
  },
  {
    $project: {
      members: {
        $map: {
          input: "$members",
          as: "m",
          in: {
            $mergeObjects: [
              "$$m",
              {
                $arrayElemAt: [
                  {
                    $filter: {
                      input: "$members_guid",
                      cond: { $eq: ["$$this._id", "$$m._id"] }
                    }
                  },
                  0
                ]
              }
            ]
          }
        }
      }
    }
  }
])