在 MongoDB 中展开 3 个数组

Posted

技术标签:

【中文标题】在 MongoDB 中展开 3 个数组【英文标题】:Unwind 3 arrays in MongoDB 【发布时间】: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"

【问题讨论】:

你总是三个元素和三个字段吗? 【参考方案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"]])

【讨论】:

docs.mongodb.com/manual/reference/operator/aggregation/map @barrypicker 我猜不出你对地图的意思,但如果你能想到更好地使用地图,请给我们一些更好的解决方案,我们在这里学到更多东西。

以上是关于在 MongoDB 中展开 3 个数组的主要内容,如果未能解决你的问题,请参考以下文章

无法连接到EC2上的MongoDB

mongo和mongod的区别

MongoDB 3.6搭建副本集

MongoDB的启动与停止

康拓展开模板

mongoDB配置