On this page本页内容
You can pass a field path operand or a document operand to unwind an array field.可以传递字段路径操作数或文档操作数以展开数组字段。
You can pass the array field path to 您可以将数组字段路径传递给$unwind. $unwind。When using this syntax, 使用此语法时,如果字段值为$unwind does not output a document if the field value is null, missing, or an empty array.null、缺失或空数组,$unwind不会输出文档。
{ $unwind: <field path> }
When you specify the field path, prefix the field name with a dollar sign 指定字段路径时,在字段名称前面加上美元符号$ and enclose in quotes.$,并用引号括起来。
You can pass a document to 您可以将文档传递给$unwind to specify various behavior options.$unwind以指定各种行为选项。
{
$unwind:
{
path: <field path>,
includeArrayIndex: <string>,
preserveNullAndEmptyArrays: <boolean>
}
}
path | string |
|
includeArrayIndex | string |
|
preserveNullAndEmptyArrays | boolean |
|
Changed in version 3.2.在版本3.2中更改。
$unwind$unwind treats the operand as a single element array. $unwind将操作数视为单元素数组。$unwind depends on the value of the preserveNullAndEmptyArrays option.null、缺失或空数组,$unwind的行为取决于preserveNullAndEmptyArrays选项的值。
Previously, if a value in the field specified by the field path is not an array, 以前,如果字段路径指定的字段中的值不是数组,则db.collection.aggregate() generates an error.db.collection.aggregate()会生成错误。
If you specify a path for a field that does not exist in an input document or the field is an empty array, 如果为输入文档中不存在的字段指定路径,或者该字段为空数组,则默认情况下,$unwind, by default, ignores the input document and will not output documents for that input document.$unwind将忽略输入文档,并且不会输出该输入文档的文档。
To output documents where the array field is missing, null or an empty array, use the preserveNullAndEmptyArrays option.若要输出缺少数组字段、空或空数组的文档,请使用preserveNullAndEmptyArrays选项。
In 在mongosh, create a sample collection named inventory with the following document:mongosh中,使用以下文档创建名为inventory的样本集合:
db.inventory.insertOne({ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] })
The following aggregation uses the 以下聚合使用$unwind stage to output a document for each element in the sizes array:$unwind阶段为sizes数组中的每个元素输出文档:
db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
The operation returns the following results:该操作返回以下结果:
{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }
Each document is identical to the input document except for the value of the 每个文档都与输入文档相同,但sizes field which now holds a value from the original sizes array.sizes字段的值除外,该字段现在保存原始sizes数组中的值。
Consider the 以clothing collection:clothing集合为例:
db.clothing.insertMany([
{ "_id" : 1, "item" : "Shirt", "sizes": [ "S", "M", "L"] },
{ "_id" : 2, "item" : "Shorts", "sizes" : [ ] },
{ "_id" : 3, "item" : "Hat", "sizes": "M" },
{ "_id" : 4, "item" : "Gloves" },
{ "_id" : 5, "item" : "Scarf", "sizes" : null }
])
如果出现以下情况,$unwind treats the sizes field as a single element array if:$unwind将大小字段视为单个元素数组:
Expand the 使用sizes arrays with $unwind:$unwind展开sizes数组:
db.clothing.aggregate( [ { $unwind: { path: "$sizes" } } ] )
The $unwind operation returns:$unwind操作返回:
{ _id: 1, item: 'Shirt', sizes: 'S' },
{ _id: 1, item: 'Shirt', sizes: 'M' },
{ _id: 1, item: 'Shirt', sizes: 'L' },
{ _id: 3, item: 'Hat', sizes: 'M' }
"_id": 1, sizes is a populated array. "_id": 1中,sizes是一个填充数组$unwind returns a document for each element in the sizes field.$unwind为sizes字段中的每个元素返回一个文档。"_id": 3, sizes resolves to a single element array."_id": 3中,sizes解析为单个元素数组。"_id": 2, "_id": 4, and "_id": 5 do not return anything because the sizes field cannot be reduced to a single element array."_id": 2, "_id": 4和"_id": 5不返回任何内容,因为sizes字段不能缩减为单个元素数组。preserveNullAndEmptyArraysincludeArrayIndexThe preserveNullAndEmptyArrays and includeArrayIndex examples use the following collection:preserveNullAndEmptyArrays和includeArrayIndex索引示例使用以下集合:
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 }
])
preserveNullAndEmptyArraysThe following 以下$unwind operation uses the preserveNullAndEmptyArrays option to include documents whose sizes field is null, missing, or an empty array.$unwind操作使用preserveNullAndEmptyArrays选项来包括sizes字段为null、缺失或空数组的文档。
db.inventory2.aggregate( [
{ $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }
] )
The output includes those documents where the 输出包括sizes field is null, missing, or an empty array: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" : 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 }
includeArrayIndexThe following 以下$unwind operation uses the includeArrayIndex option to include the array index in the output.$unwind操作使用includeArrayIndex选项在输出中包含数组索引。
db.inventory2.aggregate( [
{
$unwind:
{
path: "$sizes",
includeArrayIndex: "arrayIndex"
}
}])
The operation unwinds the 该操作将展开sizes array and includes the array index in the new arrayIndex field. sizes数组,并将数组索引包含在新的arrayIndex字段中。If the 如果sizes field does not resolve to a populated array but is not missing, null, or an empty array, the arrayIndex field is null.sizes字段未解析为填充的数组,但未丢失、空或空数组,则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 }
In 在mongosh, create a sample collection named inventory2 with the following documents:mongosh中,使用以下文档创建名为inventory2的样本集合:
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 }
])
The following pipeline unwinds the 以下管道展开sizes array and groups the resulting documents by the unwound size values:sizes数组,并根据展开的大小值对结果文档进行分组:
db.inventory2.aggregate( [ // First Stage { $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }, // Second Stage { $group: { _id: "$sizes", averagePrice: { $avg: "$price" } } }, // Third Stage { $sort: { "averagePrice": -1 } } ] )
The $unwind stage outputs a new document for each element in the sizes array. $unwind阶段为sizes数组中的每个元素输出一个新文档。The stage uses the preserveNullAndEmptyArrays option to include in the output those documents where 该阶段使用sizes field is missing, null or an empty array. preserveNullAndEmptyArrays选项在输出中包括缺少sizes字段、null或空数组的文档。This stage passes the following documents to the next stage:此阶段将以下文件传递到下一阶段:
{ "_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 }
The $group stage groups the documents by sizes and calculates the average price of each size. $group阶段按sizes对文档进行分组,并计算每个大小的平均价格。This stage passes the following documents to the next stage:此阶段将以下文档传递到下一阶段:
{ "_id" : "S", "averagePrice" : NumberDecimal("80") }
{ "_id" : "L", "averagePrice" : NumberDecimal("80") }
{ "_id" : "M", "averagePrice" : NumberDecimal("120") }
{ "_id" : null, "averagePrice" : NumberDecimal("45.25") }
The $sort stage sorts the documents by averagePrice in descending order. The operation returns the following result:$sort阶段按averagePrice按降序对文档进行排序。该操作返回以下结果:
{ "_id" : "M", "averagePrice" : NumberDecimal("120") }
{ "_id" : "L", "averagePrice" : NumberDecimal("80") }
{ "_id" : "S", "averagePrice" : NumberDecimal("80") }
{ "_id" : null, "averagePrice" : NumberDecimal("45.25") }
In 在mongosh, create a sample collection named sales with the following documents:mongosh中,使用以下文档创建名为sales的样本集合:
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("19.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")
}
]
}
])
The following operation groups the items sold by their tags and calculates the total sales amount per each tag.以下操作将按标签销售的项目分组,并计算每个标签的总销售额。
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" ] } } } } ])
The first 第一个$unwind stage outputs a new document for each element in the items array:$unwind阶段为items数组中的每个元素输出一个新文档:
{ "_id" : "1", "items" : { "name" : "pens", "tags" : [ "writing", "office", "school", "stationary" ], "price" : NumberDecimal("12.00"), "quantity" : 5 } }
{ "_id" : "1", "items" : { "name" : "envelopes", "tags" : [ "stationary", "office" ], "price" : NumberDecimal("19.95"), "quantity" : 8 } }
{ "_id" : "2", "items" : { "name" : "laptop", "tags" : [ "office", "electronics" ], "price" : NumberDecimal("800.00"), "quantity" : 1 } }
{ "_id" : "2", "items" : { "name" : "notepad", "tags" : [ "stationary", "school" ], "price" : NumberDecimal("14.95"), "quantity" : 3 } }
The second 第二个$unwind stage outputs a new document for each element in the items.tags arrays:$unwind阶段为items.tags数组中的每个元素输出一个新文档:
{ "_id" : "1", "items" : { "name" : "pens", "tags" : "writing", "price" : NumberDecimal("12.00"), "quantity" : 5 } }
{ "_id" : "1", "items" : { "name" : "pens", "tags" : "office", "price" : NumberDecimal("12.00"), "quantity" : 5 } }
{ "_id" : "1", "items" : { "name" : "pens", "tags" : "school", "price" : NumberDecimal("12.00"), "quantity" : 5 } }
{ "_id" : "1", "items" : { "name" : "pens", "tags" : "stationary", "price" : NumberDecimal("12.00"), "quantity" : 5 } }
{ "_id" : "1", "items" : { "name" : "envelopes", "tags" : "stationary", "price" : NumberDecimal("19.95"), "quantity" : 8 } }
{ "_id" : "1", "items" : { "name" : "envelopes", "tags" : "office", "price" : NumberDecimal("19.95"), "quantity" : 8 } }
{ "_id" : "2", "items" : { "name" : "laptop", "tags" : "office", "price" : NumberDecimal("800.00"), "quantity" : 1 } }
{ "_id" : "2", "items" : { "name" : "laptop", "tags" : "electronics", "price" : NumberDecimal("800.00"), "quantity" : 1 } }
{ "_id" : "2", "items" : { "name" : "notepad", "tags" : "stationary", "price" : NumberDecimal("14.95"), "quantity" : 3 } }
{ "_id" : "2", "items" : { "name" : "notepad", "tags" : "school", "price" : NumberDecimal("14.95"), "quantity" : 3 } }
The $group stage groups the documents by the tag and calculates the total sales amount of items with each tag:$group阶段按标记对文档进行分组,并计算每个标记的项目的总销售额:
{ "_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") }