我有下面的集合,我使用 MongoDB 聚合来实现输出(其中我聚合订单的所有订单行项目)并尝试合并到另一个集合中(
order
)。
[
{
"order_line_item_id": 1,
"order_id": 100,
"products": [
{
"name": "Shoe",
"hasDefect": "YES"
},
{
"name": "Pant",
"hasDefect": "NO"
},
{
"name": "Shirt",
"hasDefect": "NOT_SURE"
}
]
},
{
"order_line_item_id": 2,
"order_id": 100,
"products": [
{
"name": "Shoe",
"hasDefect": "YES"
},
{
"name": "Pant",
"hasDefect": "YES"
},
{
"name": "Shirt",
"hasDefect": "YES"
}
]
},
{
"order_line_item_id": 3,
"order_id": 101,
"products": [
{
"name": "Shoe",
"hasDefect": "YES"
},
{
"name": "Pant",
"hasDefect": "NO"
},
{
"name": "Shirt",
"hasDefect": "NOT_SURE"
}
]
}
]
我使用下面的聚合来实现输出
db.collection.aggregate([
{
$match: {
order_id: {
$eq: 100
}
}
},
{
$unwind: "$products"
},
{
$match: {
"products.name": {
$eq: "Pant"
}
}
},
{
$group: {
_id: {
order_id: "$order_id",
productName: "$products.name"
},
hasDefects: {
$push: "$products.hasDefect"
},
products: {
$push: "$products"
}
}
},
{
$set: {
hasDefect: {
$switch: {
branches: [
{
case: {
$allElementsTrue: {
$map: {
input: "$hasDefects",
as: "d",
in: {
$eq: [
"$$d",
"YES"
]
}
}
}
},
then: "YES"
},
{
case: {
$in: [
"NO",
"$hasDefects"
]
},
then: "NO"
},
{
case: {
$in: [
"NOT_SURE",
"$hasDefects"
]
},
then: "NOT_SURE"
}
],
default: "<DEFAULT>"
}
}
}
},
{
$group: {
_id: "$_id.order_id",
order_id: {
"$first": "$_id.order_id"
},
products: {
$push: {
name: "$_id.productName",
hasDefect: "$hasDefect",
lastModified: {
$dateToString: {
date: new Date(),
timezone: "America/New_York"
}
}
}
}
}
},
{
$unset: [
"_id"
]
},
{
$merge: {
into: "order_res",
on: [ "order_id" ],
whenMatched: "replace",
whenNotMatched: "insert"
}
}
])
输出可以是一个新文档,也可以是
order
文档中某个产品的更新(如下所示)。
[
{
"order_id": 100,
"products": [
{
"name": "Shoe",
"hasDefect": "YES"
},
]
}
]
我正在使用合并聚合阶段插入/更新到另一个 mongoDB 集合。
{ $merge: { into: "order", on: "order_id", whenMatched: "replace", whenNotMatched: "insert" }}
问题是这是一项更新操作,并且订单包含以前的产品,它会用这个新产品替换所有现有产品。 例如,如果订单有以下文档,则应仅更新“鞋”产品。
[
{
"order_id": 100,
"products": [
{
"name": "Shoe",
"hasDefect": "NO"
},
{
"name": "Pant",
"hasDefect": "NO"
},
{
"name": "Shirt",
"hasDefect": "NOT_SURE"
}
]
}
]
您可以使用 $mergeObjects 代替 $merge 来创建包含所需文档的新集合。 请告诉我以下查询是否适合您:
[
{
$match: {
order_id: 100
}
},
{
$unwind: "$products"
},
{
$match: {
"products.name": "Pant"
}
},
{
$group: {
_id: {
order_id: "$order_id",
productName: "$products.name"
},
hasDefects: {
$push: "$products.hasDefect"
}
}
},
{
$set: {
hasDefect: {
$switch: {
branches: [
{
case: {
$allElementsTrue: {
$map: {
input: "$hasDefects",
as: "d",
in: {
$eq: ["$$d", "YES"]
}
}
}
},
then: "YES"
},
{
case: {
$in: ["NO", "$hasDefects"]
},
then: "NO"
},
{
case: {
$in: ["NOT_SURE", "$hasDefects"]
},
then: "NOT_SURE"
}
],
default: "<DEFAULT>"
}
}
}
},
{
$project: {
order_id: "$_id.order_id",
productName: "$_id.productName",
hasDefect: "$hasDefect",
lastModified: {
$dateToString: {
date: new Date(),
timezone: "America/New_York"
}
}
}
},
{
$merge: {
into: "order",
whenMatched: [
{
$addFields: {
products: {
$map: {
input: "$$ROOT.products",
as: "product",
in: {
$cond: {
if: {
$eq: ["$$product.name", "$productName"]
},
then: {
$mergeObjects: [
"$$product",
{ hasDefect: "$hasDefect" }
]
},
else: "$$product"
}
}
}
}
}
}
],
whenNotMatched: "insert"
}
}
]
致以诚挚的问候 阿萨瓦里