当前位置: 首页 > 知识库问答 >
问题:

MongoDB聚合:将每个数组值从另一个字段添加到数组内的每个对象。合并/合并来自不同字段的两个数组

庄高谊
2023-03-14

我正处于复杂的聚合查询(具有查找和许多组/展开阶段)的中间,并且遇到来自不同字段的两个不同数组的合并问题。

至于现在,在其中一个阶段之后(在我的大查询的中间或查找之后),我有以下输出:

{
  _id: 1,
  quantity: [2, 1, 3]
  reagents: [ 
     {name: "FirstItem", other_field: ... },
     {name: "SecondItem", other_field: ... },
     {name: "ThirdItem", other_field: ... }
  ]
}

我想:

  _id: 1,
  reagents: [ 
     {name: "FirstItem", quantity: 2 },
     {name: "SecondItem", quantity: 1 },
     {name: "ThirdItem", quantity: 3 }
  ]

因此,每个[quantity]值,我想根据它的索引添加[algents]内的每个对象,比如第一个{object}内的试剂应该有第一个元素来自[quantity]

具有数组索引的架构):

quantity: [2, 1, 3, ... n]
           ↓  ↓  ↓      ↓
reagents: [1, 2, 3, ... n]

问题是:

我无法在聚合之后或之前执行此操作,因为:

>

  • 我没有必要的数据,因为它是从不同集合中查找的结果。

    之后我不能这样做,因为在这之后,我应该通过另一个字段$group数据,因此[试剂]排序顺序已丢失,无法恢复。

    UPD:我知道我可以(并且可能应该使用$unWind阶段为[试剂],但是我在Mongo手册中没有找到任何相关的聚合阶段操作符。所以如果你知道一个必要的,请告诉我。

  • 共有2个答案

    孔弘盛
    2023-03-14

    @如果您不需要在结果中保留名称和数量以外的其他字段,那么Ashh的答案将非常有效(afaik是最好的解决方案)。但如果必须保留这些字段,则必须手动添加每个字段,这有时会很繁琐。有另一个“通用”解决方案可以解决这种情况,它使用$zip操作符,设计用于按索引合并数组。

    db.collection.aggregate([
      {
        $addFields: {
          reagents: {
            $map: {
              input: {
                $zip: {
                  inputs: [
                    "$quantity",
                    "$reagents"
                  ]
                }
              },
              as: "reagent",
              in: {
                $mergeObjects: [
                  {
                    $arrayElemAt: [
                      "$$reagent",
                      1
                    ]
                  },
                  {
                    quantity: {
                      $arrayElemAt: [
                        "$$reagent",
                        0
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      }
    ])
    

    蒙哥游乐场

    慕烨烁
    2023-03-14

    您可以添加以下阶段

     { "$addFields": {
       "reagents": {
         "$map": {
           "input": { "$range": [0, { "$size": "$reagents" }] },
           "in": {
             "name": {
               "$arrayElemAt": ["$reagents.name", "$$this"]
             },
             "quantity": {
               "$arrayElemAt": ["$quantity", "$$this"]
             }
           }
         }
       }
     }}
    

    MongoPlayground

     类似资料:
    • 问题内容: 我可以使用通用的特定于Javascript / Coffeescript的习惯用法吗?主要出于好奇。 我有两个数组,一个数组由所需的键组成,另一个数组由所需的值组成,我想将其合并到一个对象中。 问题答案: var r = {}, i, keys = [‘one’, ‘two’, ‘three’], values = [‘a’, ‘b’, ‘c’];

    • 问题内容: 我有两个像这样的数组: 我想结合这两个数组,使其不包含重复项,并保留其原始键。例如,输出应为: 我已经尝试过了,但是它正在更改其原始键: 有什么办法吗? 问题答案: 只需使用: 那应该解决。因为如果一个键出现多次(例如在您的示例中),则使用字符串键,因此一个键将覆盖具有相同名称的处理键。因为在您的情况下,它们两者都具有相同的值,但这无关紧要,并且还会删除重复项。 更新:我刚刚意识到,P

    • 我有一个类似这样的数组: 我想要一个如下所示的结果对象: 我如何在Javascript中实现这一点?

    • 问题内容: 我有两个像 我希望它们合并成单个数组 问题答案: 您需要该方法。

    • 问题内容: 让我们看一个例子。 我需要合并这两个对象数组并创建以下数组: 有没有JavaScript或jQuery函数可以做到这一点? 不适合我 它返回 问题答案: 如果要在JavaScript中合并2个对象数组。你可以使用这一招 例如 输出:

    • 问题内容: 我有两个数组,我想将这两个数组合并为一个数组。请查看以下详细信息: 第一个数组: 第二个数组: 我想要这个结果。有人知道该怎么做吗? 希望你理解这个问题。先感谢您。 问题答案: 已修正 (再次) 接受无限数量的输入数组,将所有子数组作为索引数组合并到一个容器中,然后返回结果。 编辑03/2014: 提高可读性和效率