MongoDB 在 $group 和 $lookup 之后重新格式化/展平文档
MongoDB reformat / flatten document after $group and $lookup
我有一些数据、产品,它们具有属性值和该属性的 id
。
属性的标签在同一个集合中,但使用 type: "attribute"
而不是 `type: "product"。我需要加入这些,这样我就有了包括属性标签及其值的产品。
我有非常简单的样本数据她:https://gist.github.com/flowl/632243bca8f2907a672f66920ea0f793
我的聚合看起来像这样:
db.input.aggregate([
{
$unwind: "$attributes"
},
{
$lookup: {
from: "input",
localField: "attributes.id",
foreignField: "attributeId",
as: "attributeLabels"
}
},
{
$match: { "output": { $ne: [] } }
},
{
$group: {
_id: "$productId",
product: { "$first": "$$CURRENT"}
}
},
{ $group : { _id : "$product._id", data: { $push: "$$ROOT" } } }
]);
问题是,我想重新格式化输出:
{
"_id" : ObjectId("5899925339db9185f13432c4"),
"data" : [
{
"_id" : 111,
"product" : {
"_id" : ObjectId("5899925339db9185f13432c4"),
"type" : "product",
"productId" : 111,
"attributes" : {
"id" : 1,
"value" : "L"
},
"attributeLabels" : [
{
"_id" : ObjectId("5899927539db9185f13432cb"),
"type" : "attribute",
"attributeId" : 1,
"label" : "Size"
}
]
}
}
]
}
为此:
{
"_id" : ObjectId("5899925339db9185f13432c4"),
"type" : "product",
"productId" : 111,
"attributes" : [
{
"_id" : ObjectId("5899927539db9185f13432cb"),
"type" : "attribute",
"attributeId" : 1,
"label" : "Size",
"value" : "L"
}
]
}
您可以使用以下聚合。
这会将 attributes
数组中的 id
字段值替换为 $lookUp
值。
响应不完全相似,但它包括来自 product
的所有属性值。
db.input.aggregate([{
$unwind: "$attributes"
}, {
$lookup: {
from: "input",
localField: "attributes.id",
foreignField: "attributeId",
as: "attributes.id"
}
}, {
$match: {
"attributes.id": {
$ne: []
}
}
}, {
$unwind: "$attributes.id"
}, {
$group: {
_id: "$_id",
type: {
"$first": "$type"
},
productId: {
"$first": "$productId"
},
attributes: {
"$push": "$attributes"
}
}
}]);
响应示例
{
"_id": ObjectId("5899925339db9185f13432c4"),
"type": "product",
"productId": 111,
"attributes": [{
"id": {
"_id": ObjectId("5899927539db9185f13432cb"),
"type": "attribute",
"attributeId": 1,
"label": "Size"
},
"value": "L"
}]
}
我有一些数据、产品,它们具有属性值和该属性的 id
。
属性的标签在同一个集合中,但使用 type: "attribute"
而不是 `type: "product"。我需要加入这些,这样我就有了包括属性标签及其值的产品。
我有非常简单的样本数据她:https://gist.github.com/flowl/632243bca8f2907a672f66920ea0f793
我的聚合看起来像这样:
db.input.aggregate([
{
$unwind: "$attributes"
},
{
$lookup: {
from: "input",
localField: "attributes.id",
foreignField: "attributeId",
as: "attributeLabels"
}
},
{
$match: { "output": { $ne: [] } }
},
{
$group: {
_id: "$productId",
product: { "$first": "$$CURRENT"}
}
},
{ $group : { _id : "$product._id", data: { $push: "$$ROOT" } } }
]);
问题是,我想重新格式化输出:
{
"_id" : ObjectId("5899925339db9185f13432c4"),
"data" : [
{
"_id" : 111,
"product" : {
"_id" : ObjectId("5899925339db9185f13432c4"),
"type" : "product",
"productId" : 111,
"attributes" : {
"id" : 1,
"value" : "L"
},
"attributeLabels" : [
{
"_id" : ObjectId("5899927539db9185f13432cb"),
"type" : "attribute",
"attributeId" : 1,
"label" : "Size"
}
]
}
}
]
}
为此:
{
"_id" : ObjectId("5899925339db9185f13432c4"),
"type" : "product",
"productId" : 111,
"attributes" : [
{
"_id" : ObjectId("5899927539db9185f13432cb"),
"type" : "attribute",
"attributeId" : 1,
"label" : "Size",
"value" : "L"
}
]
}
您可以使用以下聚合。
这会将 attributes
数组中的 id
字段值替换为 $lookUp
值。
响应不完全相似,但它包括来自 product
的所有属性值。
db.input.aggregate([{
$unwind: "$attributes"
}, {
$lookup: {
from: "input",
localField: "attributes.id",
foreignField: "attributeId",
as: "attributes.id"
}
}, {
$match: {
"attributes.id": {
$ne: []
}
}
}, {
$unwind: "$attributes.id"
}, {
$group: {
_id: "$_id",
type: {
"$first": "$type"
},
productId: {
"$first": "$productId"
},
attributes: {
"$push": "$attributes"
}
}
}]);
响应示例
{
"_id": ObjectId("5899925339db9185f13432c4"),
"type": "product",
"productId": 111,
"attributes": [{
"id": {
"_id": ObjectId("5899927539db9185f13432cb"),
"type": "attribute",
"attributeId": 1,
"label": "Size"
},
"value": "L"
}]
}