如何将查询写入 $lookup、$group 和 $sum 以显示带有输入文档的输出
How to write a query to $lookup, $group and $sum to show the output with input document
我有 2 个集合 collection1 和 collection2。我想查找两个表并对数量进行分组和求和。我尝试在集合 2 中分组并使用集合 1 进行查找,但没有正确获取输出文档。请帮忙找出这个问题。
//collection 1
{
_id: 1,
name: Product1,
units: 20
},
{
_id: 2,
name: Product2,
units: 10
},
{
_id: 3,
name: Product3,
units: 50
},
{
_id: 4,
name: Product4,
units: 4
}
//collection2
{
_id2: 1,
inventory: 1, //foreign key
quantity: 20,
},
{
_id2: 2,
inventory: 1 //foreign key
quantity: 10
},
{
_id2: 3,
inventory: 1 //foreign key
quantity: 50
},
{
_id2: 4,
inventory: 2 //foreign key
quantity: 4
},
{
_id2: 5,
inventory: 2 //foreign key
quantity: 45
},
{
_id2: 6,
inventory: 3 //foreign key
quantity: 49
},
如何编写查询以获得像这样的 collection1 数据的输出
{
_id1: 1,
name: Product1,
units: 20,
inventoryList: [quantity: 80]
},
{
_id1: 2,
name: Product2,
units: 10,
inventoryList: [quantity: 49]
},
{
_id1: 3,
name: Product3,
units: 50,
inventoryList: [quantity: 49]
},
{
_id1: 4,
name: Product4,
units: 4,
inventoryList: [quantity: 0]
}
解决方案 #1:
db.collection1.aggregate([
{
$lookup: {
from: "collection2",
localField: "_id",
foreignField: "inventory",
as: "inventoryList"
}
},
{
$addFields: {
inventoryList: {
$reduce: {
input: "$inventoryList",
initialValue: 0,
in: {
$sum: ["$$value", "$$this.quantity"]
}
}
}
}
}
]);
解决方案#2:正如@turivishal 在以下评论中所建议的那样。
db.collection1.aggregate([
{
$lookup: {
from: "collection2",
localField: "_id",
foreignField: "inventory",
as: "inventoryList"
}
},
{
$addFields: {
inventoryList: { $sum: "$inventoryList.quantity" }
}
}
]);
输出:
/* 1 */
{
"_id" : 1,
"name" : "Product1",
"units" : 20,
"inventoryList" : 80
},
/* 2 */
{
"_id" : 2,
"name" : "Product2",
"units" : 10,
"inventoryList" : 49
},
/* 3 */
{
"_id" : 3,
"name" : "Product3",
"units" : 50,
"inventoryList" : 49
},
/* 4 */
{
"_id" : 4,
"name" : "Product4",
"units" : 4,
"inventoryList" : 0
}
解决方案 3:如果您希望它完全符合您的预期输出:
db.collection1.aggregate([
{
$lookup: {
from: "collection2",
localField: "_id",
foreignField: "inventory",
as: "inventoryList"
}
},
{
$addFields: {
inventoryList: [{ quantity: { $sum: "$inventoryList.quantity" } }]
}
}
]);
输出:
/* 1 */
{
"_id" : 1,
"name" : "Product1",
"units" : 20,
"inventoryList" : [
{
"quantity" : 80
}
]
},
/* 2 */
{
"_id" : 2,
"name" : "Product2",
"units" : 10,
"inventoryList" : [
{
"quantity" : 49
}
]
},
/* 3 */
{
"_id" : 3,
"name" : "Product3",
"units" : 50,
"inventoryList" : [
{
"quantity" : 49
}
]
},
/* 4 */
{
"_id" : 4,
"name" : "Product4",
"units" : 4,
"inventoryList" : [
{
"quantity" : 0
}
]
}
您可以尝试使用管道查找,
- 允许传递库存id和匹配表达式条件
$group
by null 和 sum quantity
db.col1.aggregate([
{
$lookup: {
from: "col2",
let: { inventory: "$_id" },
pipeline: [
{
$match: {
$expr: { $eq: ["$$inventory", "$inventory"] }
}
},
{
$group: {
_id: null,
quantity: { $sum: "$quantity" }
}
}
],
as: "inventoryList"
}
}
])
我有 2 个集合 collection1 和 collection2。我想查找两个表并对数量进行分组和求和。我尝试在集合 2 中分组并使用集合 1 进行查找,但没有正确获取输出文档。请帮忙找出这个问题。
//collection 1
{
_id: 1,
name: Product1,
units: 20
},
{
_id: 2,
name: Product2,
units: 10
},
{
_id: 3,
name: Product3,
units: 50
},
{
_id: 4,
name: Product4,
units: 4
}
//collection2
{
_id2: 1,
inventory: 1, //foreign key
quantity: 20,
},
{
_id2: 2,
inventory: 1 //foreign key
quantity: 10
},
{
_id2: 3,
inventory: 1 //foreign key
quantity: 50
},
{
_id2: 4,
inventory: 2 //foreign key
quantity: 4
},
{
_id2: 5,
inventory: 2 //foreign key
quantity: 45
},
{
_id2: 6,
inventory: 3 //foreign key
quantity: 49
},
如何编写查询以获得像这样的 collection1 数据的输出
{
_id1: 1,
name: Product1,
units: 20,
inventoryList: [quantity: 80]
},
{
_id1: 2,
name: Product2,
units: 10,
inventoryList: [quantity: 49]
},
{
_id1: 3,
name: Product3,
units: 50,
inventoryList: [quantity: 49]
},
{
_id1: 4,
name: Product4,
units: 4,
inventoryList: [quantity: 0]
}
解决方案 #1:
db.collection1.aggregate([
{
$lookup: {
from: "collection2",
localField: "_id",
foreignField: "inventory",
as: "inventoryList"
}
},
{
$addFields: {
inventoryList: {
$reduce: {
input: "$inventoryList",
initialValue: 0,
in: {
$sum: ["$$value", "$$this.quantity"]
}
}
}
}
}
]);
解决方案#2:正如@turivishal 在以下评论中所建议的那样。
db.collection1.aggregate([
{
$lookup: {
from: "collection2",
localField: "_id",
foreignField: "inventory",
as: "inventoryList"
}
},
{
$addFields: {
inventoryList: { $sum: "$inventoryList.quantity" }
}
}
]);
输出:
/* 1 */
{
"_id" : 1,
"name" : "Product1",
"units" : 20,
"inventoryList" : 80
},
/* 2 */
{
"_id" : 2,
"name" : "Product2",
"units" : 10,
"inventoryList" : 49
},
/* 3 */
{
"_id" : 3,
"name" : "Product3",
"units" : 50,
"inventoryList" : 49
},
/* 4 */
{
"_id" : 4,
"name" : "Product4",
"units" : 4,
"inventoryList" : 0
}
解决方案 3:如果您希望它完全符合您的预期输出:
db.collection1.aggregate([
{
$lookup: {
from: "collection2",
localField: "_id",
foreignField: "inventory",
as: "inventoryList"
}
},
{
$addFields: {
inventoryList: [{ quantity: { $sum: "$inventoryList.quantity" } }]
}
}
]);
输出:
/* 1 */
{
"_id" : 1,
"name" : "Product1",
"units" : 20,
"inventoryList" : [
{
"quantity" : 80
}
]
},
/* 2 */
{
"_id" : 2,
"name" : "Product2",
"units" : 10,
"inventoryList" : [
{
"quantity" : 49
}
]
},
/* 3 */
{
"_id" : 3,
"name" : "Product3",
"units" : 50,
"inventoryList" : [
{
"quantity" : 49
}
]
},
/* 4 */
{
"_id" : 4,
"name" : "Product4",
"units" : 4,
"inventoryList" : [
{
"quantity" : 0
}
]
}
您可以尝试使用管道查找,
- 允许传递库存id和匹配表达式条件
$group
by null 和 sumquantity
db.col1.aggregate([
{
$lookup: {
from: "col2",
let: { inventory: "$_id" },
pipeline: [
{
$match: {
$expr: { $eq: ["$$inventory", "$inventory"] }
}
},
{
$group: {
_id: null,
quantity: { $sum: "$quantity" }
}
}
],
as: "inventoryList"
}
}
])