美文网首页数据库mongodb基础操作
mongodb Aggregation聚合操作之$unwind

mongodb Aggregation聚合操作之$unwind

作者: 蚁族的乐土 | 来源:发表于2021-03-04 17:16 被阅读0次

    在上一篇 mongodb Aggregation聚合操作之$project 中详细介绍了mongodb聚合操作中的$project使用以及参数细节。本篇将开始介绍Aggregation聚合操作中的unwind操作。

    说明:

    解析输入文档中的数组字段,为每个元素输出一个文档。每个输出文档都是输入文档,数组字段的值被元素替换。如果字段值为null、缺失或数组为空,则$unwind不会输出文档。

    语法:

    { $unwind: <field path> }

    可以将文档传递给$unwind以指定各种行为选项。

    {

      $unwind:

        {

          path: <field path>,

          includeArrayIndex: <string>,

          preserveNullAndEmptyArrays: <boolean>

        }

    }

    参数解析:

    path:string类型,数组字段的字段路径。若要指定字段路径,请在字段名称前加上美元符号$并将其括在引号中。

    includeArrayIndex:string类型,可选的。用于保存元素的数组索引的新字段的名称。新字段名称不能以美元符号$开头。

    preserveNullAndEmptyArrays:boolean类型,可选的。如果为真,如果路径为空、丢失或数组为空,则$unwind输出文档。如果为false,如果路径为空、丢失或数组为空,则$unwind不输出文档。默认值为false。

    1. 示例

    1.1. 简单示例

    初始化数据:

    db.inventory.insertOne({ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] })

    示例:按照sizes字段拆分数据

    db.inventory.aggregate( [ { $unwind : "$sizes" } ] )

    结果:

    { "_id" : 1, "item" : "ABC1", "sizes" : "S" }

    { "_id" : 1, "item" : "ABC1", "sizes" : "M" }

    { "_id" : 1, "item" : "ABC1", "sizes" : "L" }

    1.2. 拆分数组字段是null或者[]数据

    初始化数据:

    db.inventory2.insertMany([

      { "_id" : 1, "item" : "ABC", price: NumberDecimal("80"), "sizes": [ "S", "M", "L"] },

      { "_id" : 2, "item" : "EFG", price: NumberDecimal("120"), "sizes" : [ ] },

      { "_id" : 3, "item" : "IJK", price: NumberDecimal("160"), "sizes": "M" },

      { "_id" : 4, "item" : "LMN" , price: NumberDecimal("10") },

      { "_id" : 5, "item" : "XYZ", price: NumberDecimal("5.75"), "sizes" : null }

    ])

    示例:

    下面的$unwind操作是等效的,并为size字段中的每个元素返回一个文档。如果size字段没有解析为数组,但没有丢失、null或空数组,则$unwind将非数组操作数视为单个元素数组。

    db.inventory2.aggregate( [ { $unwind: "$sizes" } ] )

    db.inventory2.aggregate( [ { $unwind: { path: "$sizes" } } ] )

    结果:

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "S" }

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "M" }

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "L" }

    { "_id" : 3, "item" : "IJK", "price" : NumberDecimal("160"), "sizes" : "M" }

    示例:下面的$unwind操作使用includeArrayIndex选项在输出中包含数组索引。

    db.inventory2.aggregate( [

      {

        $unwind:

          {

            path: "$sizes",

            includeArrayIndex: "arrayIndex"

          }

       }])

    结果:

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "S", "arrayIndex" : NumberLong(0) }

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "M", "arrayIndex" : NumberLong(1) }

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "L", "arrayIndex" : NumberLong(2) }

    { "_id" : 3, "item" : "IJK", "price" : NumberDecimal("160"), "sizes" : "M", "arrayIndex" : null }

    示例:下面的$unwind操作使用preserveNullAndEmptyArrays选项来包含size字段为null、缺失或空数组的文档。

    db.inventory2.aggregate( [

       { $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }

    ] )

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "S" }

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "M" }

    { "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "L" }

    { "_id" : 2, "item" : "EFG", "price" : NumberDecimal("120") }

    { "_id" : 3, "item" : "IJK", "price" : NumberDecimal("160"), "sizes" : "M" }

    { "_id" : 4, "item" : "LMN", "price" : NumberDecimal("10") }

    { "_id" : 5, "item" : "XYZ", "price" : NumberDecimal("5.75"), "sizes" : null }

    1.3. 拆分数组字段并分组

    初始化数据:

    db.inventory2.insertMany([

      { "_id" : 1, "item" : "ABC", price: NumberDecimal("80"), "sizes": [ "S", "M", "L"] },

      { "_id" : 2, "item" : "EFG", price: NumberDecimal("120"), "sizes" : [ ] },

      { "_id" : 3, "item" : "IJK", price: NumberDecimal("160"), "sizes": "M" },

      { "_id" : 4, "item" : "LMN" , price: NumberDecimal("10") },

      { "_id" : 5, "item" : "XYZ", price: NumberDecimal("5.75"), "sizes" : null }

    ])

    示例:下面的管道将展开大小数组,并将产生的文档按展开后的大小值进行分组:

    db.inventory2.aggregate( [

       // First Stage

       {

         $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true }

       },

       // Second Stage

       {

         $group:

           {

             _id: "$sizes",

             averagePrice: { $avg: "$price" }

           }

       },

       // Third Stage

       {

         $sort: { "averagePrice": -1 }

       }

    ] )

    结果:

    { "_id" : "M", "averagePrice" : NumberDecimal("120") }

    { "_id" : "L", "averagePrice" : NumberDecimal("80") }

    { "_id" : "S", "averagePrice" : NumberDecimal("80") }

    { "_id" : null, "averagePrice" : NumberDecimal("45.25") }

    1.4. 拆分嵌入式数组文档

    初始化数据:

    db.sales.insertMany([

      {

        _id: "1",

        "items" : [

         {

          "name" : "pens",

          "tags" : [ "writing", "office", "school", "stationary" ],

          "price" : NumberDecimal("12.00"),

          "quantity" : NumberInt("5")

         },

         {

          "name" : "envelopes",

          "tags" : [ "stationary", "office" ],

          "price" : NumberDecimal("1.95"),

          "quantity" : NumberInt("8")

         }

        ]

      },

      {

        _id: "2",

        "items" : [

         {

          "name" : "laptop",

          "tags" : [ "office", "electronics" ],

          "price" : NumberDecimal("800.00"),

          "quantity" : NumberInt("1")

         },

         {

          "name" : "notepad",

          "tags" : [ "stationary", "school" ],

          "price" : NumberDecimal("14.95"),

          "quantity" : NumberInt("3")

         }

        ]

      }

    ])

    示例:下面的操作将按标签销售的商品分组,并计算每个标签的总销售额。

    db.sales.aggregate([

      // First Stage

      { $unwind: "$items" },

      // Second Stage

      { $unwind: "$items.tags" },

      // Third Stage

      {

        $group:

          {

            _id: "$items.tags",

            totalSalesAmount:

              {

                $sum: { $multiply: [ "$items.price", "$items.quantity" ] }

              }

          }

      }

    ])

    结果:

    { "_id" : "writing", "totalSalesAmount" : NumberDecimal("60.00") }

    { "_id" : "stationary", "totalSalesAmount" : NumberDecimal("264.45") }

    { "_id" : "electronics", "totalSalesAmount" : NumberDecimal("800.00") }

    { "_id" : "school", "totalSalesAmount" : NumberDecimal("104.85") }

        { "_id" : "office", "totalSalesAmount" : NumberDecimal("1019.60") }

    相关文章

      网友评论

        本文标题:mongodb Aggregation聚合操作之$unwind

        本文链接:https://www.haomeiwen.com/subject/hcmkqltx.html