我有一个包含对象的集合,每个对象都包含多个array.例如:

assmemblies: { 
  mechanicalItems: [{ 
    mechanicalId: <ObjectId that references the mechanicalitems collection>,
    quantity: Number
  }],
  electricalItems: [{ 
    mechanicalId: <ObjectId that references the mechanicalitems collection>
    quantity: Number
}],

我正在try 执行一次查找,以将mechanicalitemselectricalitems中的所有字段都放入程序集集合中,但是很难使$lookup工作.

当我试图展开和分组时,我丢失了另一个数组,或者它最终嵌套在另一个数组中的每个数组对象中.

我还try 直接投射回Quantity属性,但是我得到了一个包含所有数量的数组:

{
    $lookup: {
      from: "mechanicalitems",
      let: {
        mechanicalItem: "$mechanicalItems",
        item: "$machanicalItems.mechanicalId",
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $in: ["$_id", "$$item"],
            },
          },
        },
        {
          $project: {
            "quantity": "$$mechanicalItem.quantity" // <-- this gives an array of all the quantities
          }
        },
      ],
      as: "mechanicalItems",
    },
  },

我试过其他几种 Select ,但都不能完全得到我想要的.

*编辑-预期输出

如果我的mechanicalItems个域是:‘尺寸’、‘material ’、‘风格’,而我的electricalItems个域是:‘当前’、‘评级’、‘绝缘’,那么我的预期输出是:

assemblies: {
  mechanicalItems: [{
    item: {
      _id: <some ObjectId>
      size: '12',
      material: 'steel',
      style: 'thick'
    },
    quantity: Number
 }, ...
 ],
 electricalItems: [{
    item: {
      _id: <some ObjectId>
      current: '15',
      rating: 'low voltage',
      insulation: 'PVC'
    },
    quantity: Number
  }, ...
  ]
}

我希望用MachicalItems集合中的实际对象替换mechanicalItemId(并最终将该字段重命名为"Item",但稍后我可以用$addFields$project来实现这一点).

推荐答案

  1. 有一个打字错误:$machanicalItems.mechanicalId,应该是$mechanicalItems.mechanicalId.

  2. mechanicalItem.quantity返回一个数字数组,因为mechanicalItem是一个array.相反,您需要为mechanicalItem数组的匹配文档获取单个quantity值,并将其设置为quantity字段.

db.assemblies.aggregate([
  {
    $lookup: {
      from: "mechanicalitems",
      let: {
        mechanicalItem: "$mechanicalItems",
        item: "$mechanicalItems.mechanicalId"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $in: [
                "$_id",
                "$$item"
              ]
            }
          }
        },
        {
          $set: {
            "quantity": {
              $first: {
                $map: {
                  input: {
                    $filter: {
                      input: "$$mechanicalItem",
                      cond: {
                        $eq: [
                          "$_id",
                          "$$this.mechanicalId"
                        ]
                      }
                    }
                  },
                  in: "$$this.quantity"
                }
              }
            }
          }
        }
      ],
      as: "mechanicalItems"
    }
  }
])

当您使用electricalItems集合查找联接时,electricalItems数组的逻辑是相同的.

Demo @ Mongo Playground

Mongodb相关问答推荐

MongoDB 4.4如何使用未知密钥更新dict

为什么AllowDiskUse不能在$GROUP阶段的聚合管道中工作?

MongoDB通过查找具有多个数组的对象进行聚合

如何在Mongo中查找数组中的特定对象

带有 mongodb 和 nodejs 的实时 Web 应用程序

在 Mongoose 中清理用户输入

Mongodb将重音字符匹配为基础字符

pymongo 排序和 find_one 问题

如何使用sailsjs v0.10连接mongodb?

MongoDB - 清除嵌套数组中的元素

如何在mongoose中加入两个集合

当前的 URL 字符串解析器已弃用

使用 Spring Security + Spring 数据 + MongoDB 进行身份验证

使用 MongoDB 的 map/reduce 来分组两个字段

MongoDB聚合将字符串数组连接到单个字符串

try 启用 Mongo DB 身份验证时发生 TypeError

查询不等于 null 或空的地方

mongoose:按字母顺序排序

从 nodejs 到 mongodb 或 mongoose 的动态数据库连接

MongoDB 引用的最佳实践