$unwind(聚合)

在本页面

  • 定义

  • 行为

  • 例子

定义

  • $unwind

    • 从输入文档解构 array 字段以输出每个元素的文档。每个输出文档都是输入文档,array 字段的 value 由元素替换。

$unwind阶段有两种语法之一:

  • 操作数是一个字段路径:
{ $unwind: <field path> }

要指定字段路径,请在字段 name 前加上美元符号$,并用引号括起来。

  • 操作数是一个文件:

version 3.2 中的新内容。

{
  $unwind:
    {
      path: <field path>,
      includeArrayIndex: <string>,
      preserveNullAndEmptyArrays: <boolean>
    }
}
领域类型描述
patharray 字段的字段路径。要指定字段路径,请在字段 name 前加上美元符号$,并用引号括起来。
includeArrayIndex可选的。用于保存元素的 array 索引的新字段的 name。 name 不能以美元符号$开头。
preserveNullAndEmptyArraysboolean可选的。如果true,如果path为空,缺失或空 array,则$unwind输出文档。如果false,如果path为空,缺少或空 array,则$unwind不输出文档。
默认 value 是false

行为

Non-Array Field Path

version 3.2:$unwind阶段中的更改不再是 non-array 操作数上的错误。如果操作数未解析为 array 但未丢失,null 或空 array,则$unwind将操作数视为单个元素 array。

以前,如果字段路径指定的字段中的 value 不是 array,则db.collection.aggregate()会生成错误。

缺少场

如果为输入文档中不存在的字段指定路径,或者该字段为空 array,则$unwind默认忽略输入文档,不会输出该输入文档的文档。

version 中新增 3.2:要输出缺少 array 字段的文档,null 或空 array,请使用选项preserveNullAndEmptyArrays

例子

放松 Array

考虑使用以下文档的inventory

{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }

以下聚合使用$unwind阶段为sizes array 中的每个元素输出文档:

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

该操作返回以下结果:

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

除了sizes字段的 value 之外,每个文档都与输入文档相同,后者现在包含原始sizes array 的 value。

也可以看看
使用 Zip Code 数据集进行聚合,使用用户首选项数据进行聚合

includeArrayIndex 和 preserveNullAndEmptyArrays

version 3.2 中的新内容。

集合inventory具有以下文档:

{ "_id" : 1, "item" : "ABC", "sizes": [ "S", "M", "L"] }
{ "_id" : 2, "item" : "EFG", "sizes" : [ ] }
{ "_id" : 3, "item" : "IJK", "sizes": "M" }
{ "_id" : 4, "item" : "LMN" }
{ "_id" : 5, "item" : "XYZ", "sizes" : null }

以下$unwind操作是等效的,_return sizes字段中每个元素的文档。如果sizes字段未解析为 array 但未丢失,null 或空 array,则$unwind将 non-array 操作数视为单个元素 array。

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

该操作返回以下文档:

{ "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
{ "_id" : 3, "item" : "IJK", "sizes" : "M" }

以下$unwind操作使用includeArrayIndex选项同时输出 array 元素的 array 索引。

db.inventory.aggregate( [ { $unwind: { path: "$sizes", includeArrayIndex: "arrayIndex" } } ] )

该操作展开sizes array 并在新arrayIndex字段中包含 array 索引的 array 索引。如果sizes字段未解析为 array 但未丢失,null 或空 array,则arrayIndex字段为null

{ "_id" : 1, "item" : "ABC", "sizes" : "S", "arrayIndex" : NumberLong(0) }
{ "_id" : 1, "item" : "ABC", "sizes" : "M", "arrayIndex" : NumberLong(1) }
{ "_id" : 1, "item" : "ABC", "sizes" : "L", "arrayIndex" : NumberLong(2) }
{ "_id" : 3, "item" : "IJK", "sizes" : "M", "arrayIndex" : null }

以下$unwind操作使用preserveNullAndEmptyArrays选项在输出中包含缺少sizes字段的文档,null 或空 array。

db.inventory.aggregate( [
   { $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }
] )

除了展开sizes是_ar元素或 non-null,non-array 字段的文档之外,操作输出而不修改那些sizes字段缺失的文档,null 或空 array:

{ "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
{ "_id" : 2, "item" : "EFG" }
{ "_id" : 3, "item" : "IJK", "sizes" : "M" }
{ "_id" : 4, "item" : "LMN" }
{ "_id" : 5, "item" : "XYZ", "sizes" : null }