2

具有多个数组的 MongoDB 集合数据:

{
    "_id": ObjectId("61aa6bf1742b00f59b894eb7"),
    "first": ["abc", "def", "ghi"], 
    "last": ["rst", "uvw", "xyz"],
    "numb": ["12", "34", "56"]
}

数组中的数据应采用以下格式的预期输出:

{
    "first": "abc",
    "last": "rst",
    "numb": "12"
},
{
    "first": "def",
    "last": "uvw",
    "numb": "34"
},
{
    "first": "ghi",
    "last": "xyz",
    "numb": "56"
}
4

2 回答 2

1

您可以使用$zip“转置”多个数组(实际数量多少):

// {
//   first: ["abc", "def", "ghi"],
//   last:  ["rst", "uvw", "xyz"],
//   numb:  ["12", "34", "56"]
// }
db.collection.aggregate([

  { $project: { x: { $zip: { inputs: ["$first", "$last", "$numb"] } } } },
  // { x: [["abc", "rst", "12"], ["def", "uvw", "34"], ["ghi", "xyz", "56" ]] }

  { $unwind: "$x" },
  // { x: [ "abc", "rst", "12" ] }
  // { x: [ "def", "uvw", "34" ] }
  // { x: [ "ghi", "xyz", "56" ] }

  { $replaceWith: {
    $arrayToObject: { $zip: { inputs: [["first", "last", "numb"], "$x"] } }
  }} 
])
// { first: "abc", last: "rst", numb: "12" }
// { first: "def", last: "uvw", numb: "34" }
// { first: "ghi", last: "xyz", numb: "56" }

这个:

  • zips 3 个数组,这样同一索引处的元素将被分组到同一个子数组中。

  • $unwinds (爆炸/展平)那些子阵列。

  • 将生成的数组转换为对象以适合您预期的输出格式:

    • 通过$zipping (再次!)我们想要与数组的值关联的键(键:["first", "last", "numb"]和值"$x":)
    • $replaceWith当前文档的结果$zip

请注意,在 Mongo 之前4.2,您可以使用$replaceRoot代替$replaceWith.

于 2021-12-03T22:28:25.480 回答
0

询问

  • 映射索引以将相同的索引成员组合到 1 个文档
  • 保持_id也知道这些来自哪个文档以及要排序的索引
  • 对于每个索引,从每个数组中获取元素
  • 放松
  • sort by_idindex让结果像在数组中一样排序

*索引是使用最大的数组计算的,为了安全起见,如果您已经知道所有的大小都相同,您可以将 : 替换
{"$max": [{"$size": "$first"}, {"$size": "$last"}, {"$size": "$numb"}]} 为任何数组的大小,例如(我们需要最大的才能工作):
{"$size": "$first"}

测试代码在这里

aggregate(
[{"$project": 
    {"data": 
      {"$map": 
        {"input": 
          {"$range": 
            [0,
              {"$max": 
                [{"$size": "$first"}, {"$size": "$last"}, {"$size": "$numb"}]}]},
          "in": 
          {"_id": "$_id",
           "index": "$$this",
           "first": {"$arrayElemAt": ["$first", "$$this"]},
           "last": {"$arrayElemAt": ["$last", "$$this"]},
           "numb": {"$arrayElemAt": ["$numb", "$$this"]}}}}}},
  {"$unwind": {"path": "$data"}},
  {"$replaceRoot": {"newRoot": "$data"}},
  {"$sort": {"_id": 1, "index": 1}},
  {"$unset": ["index"]}])
于 2021-12-03T21:00:14.130 回答