Rya*_*mos 4 lookup mongodb spring-mongo mongodb-query aggregation-framework
我有这些收藏
采购订单
{
"_id": "5f0104a8d0c3a06fc9c06625",
"purchaseItems": [
{
"product": "5eff29e9e2708a0ca980762e",
"quantity": 1
},
{
"product": "5eff29e9e2708a0ca980762e",
"quantity": 2
}
],
"totalQuantity": 0,
"documentDate": {
"$date": "2020-07-04T16:00:00.000Z"
}
}
Run Code Online (Sandbox Code Playgroud)
和
产品
{
"_id": "5eff29e9e2708a0ca980762e",
"name": "name",
"code": "code",
"cost": "1",
"srp": "1",
"minimum": "1",
"startEffectiveDate": {
"$date": "2020-07-04T16:00:00.000Z"
}
}
Run Code Online (Sandbox Code Playgroud)
如何将 buyItems 中的产品字段加入到产品集合中,该购买项目是一个嵌入式数组文档。我需要这样的东西。
{
"_id": "5f0104a8d0c3a06fc9c06625",
"purchaseItems": [
{
"product": {
"_id": "5eff29e9e2708a0ca980762e",
"name": "product name"
},
"quantity": 1
},
{
"product": {
"_id": "5eff29e9e2708a0ca980762e",
"name": "product name 2"
},
"quantity": 1
}
],
"totalQuantity": 0,
"documentDate": {
"$date": "2020-07-04T16:00:00.000Z"
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用此聚合,但得到了错误的结果
[{$lookup: {
from: 'product',
'let': {
purchaseItems: '$purchaseItems'
},
pipeline: [
{
$lookup: {
from: 'product',
'let': {
product: '$product'
},
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$product" ] } } }
],
"as": "product"
}
}
],
as: 'purchaseItems'
} }]
Run Code Online (Sandbox Code Playgroud)
对 mongodb 不太熟悉,我已经在考虑回到 SQL。
不要放弃。我们可以通过两种解决方案获得所需的结果:
$lookup
+$project
A。$map
允许我们迭代数组并对其进行转换(添加/保留/删除字段)
b.$filter
允许从数组
c 中获取匹配的项目。由于$filter
返回一个数组,我们需要使用$arrayElemAt
运算符来获取单个项目或应用$unwind
db.purchaseorder.aggregate([
{
"$lookup": {
"from": "product",
"localField": "purchaseItems.product",
"foreignField": "_id",
"as": "product"
}
},
{
$project: {
documentDate: 1,
totalQuantity: 1,
purchaseItems: {
$map: {
input: "$purchaseItems",
as: "item",
in: {
product: {
$arrayElemAt: [
{
$filter: {
input: "$product",
as: "prod",
cond: {
$eq: [
"$$prod._id",
"$$item.product"
]
}
}
},
0
]
},
quantity: "$$item.quantity"
}
}
}
}
}
])
Run Code Online (Sandbox Code Playgroud)
$lookup
由于 MongoDBv3.6
$lookup
允许执行非标准查询来连接 2 个或更多
集合 我们purchaseItems
在查找管道内传递
b。按产品_id
值进行匹配。
C。应用$filter
,我们只得到相关的数量值
d。我们使用运算符$unwind
(记住$filter
返回一个数组)
e 来展平数量字段。$project
我们用stage转换为所需的输出
db.purchaseorder.aggregate([
{
"$lookup": {
"from": "product",
"let": {
purchaseItems: "$purchaseItems"
},
"pipeline": [
{
$match: {
$expr: {
$in: [
"$_id",
"$$purchaseItems.product"
]
}
}
},
{
$addFields: {
quantity: {
$filter: {
input: "$$purchaseItems",
as: "purch",
cond: {
$eq: [
"$$purch.product",
"$_id"
]
}
}
}
}
},
{
$unwind: "$quantity"
},
{
$project: {
_id: 0,
product: {
_id: "$_id",
name: "$name"
},
quantity: "$quantity.quantity"
}
}
],
"as": "purchaseItems"
}
}
])
Run Code Online (Sandbox Code Playgroud)