$unwind
将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$unwind 两种语法结构
1. 指定 要拆分字段的路径path
{ $unwind: <field path> }
2. 指定一个文档格式
New in version 3.2.
{
$unwind:
{
path: <field path>,
includeArrayIndex: <string>,
preserveNullAndEmptyArrays: <boolean>
}
}
示例
拆分数组
现有集合 inventory 内容如下:
db.inventory.insert({ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] })
下面的聚合 使用$unwind 让数组中的每个元素输出一个文档:
db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
执行返回如下结果:
{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }
includeArrayIndex and preserveNullAndEmptyArrays
现有集合 inventory 内容如下:
db.inventory.insert([{ "_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
操作是等效的,并为sizes
字段中的每个元素返回一个文档。
db.inventory.aggregate( [ { $unwind: "$sizes" } ] )
db.inventory.aggregate( [ { $unwind: { path: "$sizes" } } ] )
注意:如果sizes
字段不能解析成数组,但又不属于情况(不存在,null,或一个空数组,处理方式:丢弃),$unwind
将视为一个单数组操作。
执行返回如下结果:
{ "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
{ "_id" : 3, "item" : "IJK", "sizes" : "M" }
指定索引号 includeArrayIndex
以下的 $unwind
操作 使用了 includeArrayIndex
选项输出数组元素的数组索引。
db.inventory.aggregate( [ { $unwind: { path: "$sizes", includeArrayIndex: "arrayIndex" } } ] )
此操作 拆分sizes
字段,返回数组每个元素的的索引值
{ "_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 }
注意:如果 sizes
字段 不能解析成数组,但又不属于情况(不存在,null,或者是空数组)的话,索引值字段为null
问题:数据出现了丢失情况,sizes为不存在,[] 或者null时,数据丢失
$unwind
使用preservenullandemptyarrays
选项 可以 输出sizes
字段(不存在、null或空数组)的这些文档。
db.inventory.aggregate( [
{ $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }
] )
此操作执行返回如下结果:
{ "_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 }
小结:
{
$unwind:
{
path: <field path>, #拆分路径
includeArrayIndex: <string>, #指定数组索引号
preserveNullAndEmptyArrays: <boolean> #防止数据丢失
}
}