【问题标题】:Unwind 3 arrays in MongoDB在 MongoDB 中展开 3 个数组
【发布时间】:2022-01-10 04:00:14
【问题描述】:

具有多个数组的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"
}

【问题讨论】:

  • 你总是三个元素和三个字段吗?

标签: arrays mongodb mongodb-query unwind


【解决方案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

【讨论】:

  • 很好,我考虑过使用 zip,但后来我不这么认为,你也让它简洁,也许添加`useLongestLength: ` 并排序,但也许 OP 不关心这些.
【解决方案2】:

查询

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

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

Test code here

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"]}])

【讨论】:

猜你喜欢
  • 2017-01-15
  • 2014-04-02
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
  • 2019-04-10
  • 2017-03-03
相关资源
最近更新 更多