• MongoDB聚合运算符:$zip


    MongoDB聚合运算符:$zip


    $zip用于将输入数组的元素重新组合转换为新的数组,重组转换的的规则是使用输入数组的第一个元素重组为第一个数组,使用第二个元素重组为第二个数组,以此类推。

    例如,[ [ 1, 2, 3 ], [ "a", "b", "c" ] ]转换后为[ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]

    语法

    {
        $zip: {
            inputs: [ <array expression1>,  ... ],
            useLongestLength: <boolean>,
            defaults:  <array expression>
        }
    }
    
    • inputs:表达式数组,数组的每个表达式可解析为数组。这些输入数组的元素组合成输出数组。
      如果任何一个输入数组的解析值为空或指向一个缺失字段,$zip将返回空值。
      如果输入数组中的任何一个没有解析为数组或空值,或者指向一个缺失字段,$zip将返回错误信息。
    • useLongestLength:布尔值,用于指定最长数组的长度是否决定输出数组中数组的个数。
      默认值为 false,最短数组的长度决定输出数组中数组的个数。
    • 如果输入数组的长度不同,则使用默认元素值数组。必须同时指定 useLongestLength: true,否则$zip将返回错误。
      如果useLongestLength: true,但defaults为空或未指定,$zip将使用null作为默认值。
      如果指定了非空defaults,则必须为每个输入数组指定默认值,否则$zip返回错误。

    使用

    输入数组的长度不要求相同。默认情况下,输出数组的长度为最短输入数组的长度,但useLongestLength选项可以指定$zip输出与最长输入数组的长度是否一致。

    参考下面的例子来说明:

    例1:

    { $zip: { inputs: [ [ "a" ], [ "b" ], [ "c" ] ] }}
    

    结果:

    [ [ "a", "b", "c" ] ]
    

    例2:

    { $zip: { inputs: [ [ "a" ], [ "b", "c" ] ] } }
    

    结果:

    [ [ "a", "b" ] ]
    

    例3:

    {
      $zip: {
         inputs: [ [ 1 ], [ 2, 3 ] ],
         useLongestLength: true
      }
    }
    

    结果:

    [ [ 1, 2 ], [ null, 3 ] ]
    

    例4:

    {
      $zip: {
         inputs: [ [ 1 ], [ 2, 3 ], [ 4 ] ],
         useLongestLength: true,
         defaults: [ "a", "b", "c" ]
      }
    }
    

    结果:

    因为useLongestLength: true$zip会用缺省值元素填充较短的输入数组。

    [ [ 1, 2, 4 ], [ "a", 3, "c" ] ]
    

    举例

    矩阵转置

    使用下面的脚本创建matrices集合:

    db.matrices.insertMany([
      { matrix: [[1, 2], [2, 3], [3, 4]] },
      { matrix: [[8, 7], [7, 6], [5, 4]] },
    ])
    

    要计算这个集合中每个 3x2 矩阵的转置,可以使用下面的聚合运算:。

    db.matrices.aggregate([{
      $project: {
        _id: false,
        transposed: {
          $zip: {
            inputs: [
              { $arrayElemAt: [ "$matrix", 0 ] },
              { $arrayElemAt: [ "$matrix", 1 ] },
              { $arrayElemAt: [ "$matrix", 2 ] },
            ]
          }
        }
      }
    }])
    

    执行的结果为:

    { "transposed" : [ [ 1, 2, 3 ], [ 2, 3, 4 ] ] }
    { "transposed" : [ [ 8, 7, 5 ], [ 7, 6, 4 ] ] }
    

    过滤并保留索引

    可以使用$zip$filter来获取数组中的元素子集,同时保存每个元素的原始索引。

    使用脚本创建pages集合:

    db.pages.insertOne( {
      "category": "unix",
      "pages": [
        { "title": "awk for beginners", reviews: 5 },
        { "title": "sed for newbies", reviews: 0 },
        { "title": "grep made simple", reviews: 2 },
    ] } )
    

    下面的聚合首先把pages数组中的元素连同其索引一起压缩,然后只筛选出至少有一条评论的页面::

    db.pages.aggregate([{
      $project: {
        _id: false,
        pages: {
          $filter: {
            input: {
              $zip: {
                inputs: [ "$pages", { $range: [0, { $size: "$pages" }] } ]
              }
            },
            as: "pageWithIndex",
            cond: {
              $let: {
                vars: {
                  page: { $arrayElemAt: [ "$$pageWithIndex", 0 ] }
                },
                in: { $gte: [ "$$page.reviews", 1 ] }
              }
            }
          }
        }
      }
    }])
    

    结果为:

    {
      "pages" : [
        [ { "title" : "awk for beginners", "reviews" : 5 }, 0 ],
        [ { "title" : "grep made simple", "reviews" : 2 }, 2 ] ]
    }
    
  • 相关阅读:
    【正点原子STM32连载】 第三十八章 红外遥控实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
    Spring-boot-starter-actuator的可视化spring-boot-admin
    阿里的数据同步神器——Canal
    2023年数学建模国赛A 定日镜场的优化设计思路分析
    Obsidian基础教程
    Diffusion Autoencoders: Toward a Meaningful and Decodable Representation
    c++ 经典服务器开源项目 Tinywebserver的使用与配置(百度智能云服务器安装ubuntu18.04可用公网ip访问)
    介绍document部分自带的方法及属性,场景使用例如倒计时等
    2311rust,到74版本更新
    CLIP模型资料学习
  • 原文地址:https://blog.csdn.net/superatom01/article/details/138905808