[英]MongoDB sum of fields inside objects inside an array that is inside of an object greater than x
//8. isbn 至少售出 X 本的书籍数量(您决定 X 的价值)。
图书示例
{
isbn: "0001",
title: "Book1",
pages: NumberInt("150"),
price: NumberDecimal("321.2"),
copies: NumberInt("3"),
language: "english",
author: ["Author1"],
category: ["Space Opera"],
genre: ["Genre-1", "Genre-2"],
character: ["Character-1", "Character-2"],
},
订单示例
{
orderNo: "3",
customerNo: "0003",
date: {
day: NumberInt("25"),
month: NumberInt("02"),
year: NumberInt("2021"),
},
orderLine: [
{
isbn: "0006",
price: NumberDecimal("341.0"),
amount: NumberInt("2"),
},
{
isbn: "0007",
price: NumberDecimal("170.5"),
amount: NumberInt("1"),
},
],
},
我的尝试 我相信我在小组赛阶段的管道中有一个错误。 现在,我至少需要 isbn 以及在 object 中出售的副本。
db.books.aggregate([ // editing this
{ $match : {} },
{
$lookup :
{
from : "orders",
pipeline : [
{
$group :
{
_id: null,
amount_total : { $sum : "$orderLine.amount" }
}
},
{ $project : { _id : 0, amount_total : 1} }
],
as : "amount"
}
},
{ $project : { _id : 0, isbn : 1, amount : 1} }
])
不知道为什么都是 0,我期待至少有一些不同的数字。
{
"isbn": "0001",
"amount": [
{
"amount_total": 0
}
]
},
{
"isbn": "0002",
"amount": [
{
"amount_total": 0
}
]
},
{
"isbn": "0003",
"amount": [
{
"amount_total": 0
}
]
},// and so on
在您的查询中$lookup
正在执行一个没有任何条件的连接操作,而不是尝试这个查询:
db.books.aggregate([
{
$lookup: {
from: "orders",
let: { isbn: "$isbn" },
pipeline: [
{ $unwind: "$orderLine" },
{
$match: {
$expr: { $eq: ["$orderLine.isbn", "$$isbn"] }
}
}
],
as: "amount"
}
},
{
$project: {
_id: 0,
isbn: 1,
amount_total: { $sum: "$amount.orderLine.amount" }
}
}
]);
测试数据:
books
收藏:
/* 1 createdAt:3/12/2021, 10:41:13 AM*/
{
"_id" : ObjectId("604af7f14b5860176c2254b7"),
"isbn" : "0001",
"title" : "Book1"
},
/* 2 createdAt:3/12/2021, 10:41:13 AM*/
{
"_id" : ObjectId("604af7f14b5860176c2254b8"),
"isbn" : "0002",
"title" : "Book2"
}
orders
集合:
/* 1 createdAt:3/12/2021, 11:10:51 AM*/
{
"_id" : ObjectId("604afee34b5860176c2254ce"),
"orderNo" : "1",
"customerNo" : "0001",
"orderLine" : [
{
"isbn" : "0001",
"price" : 341,
"amount" : 2
},
{
"isbn" : "0002",
"price" : 170.5,
"amount" : 1
},
{
"isbn" : "0003",
"price" : 190.5,
"amount" : 3
}
]
},
/* 2 createdAt:3/12/2021, 11:10:51 AM*/
{
"_id" : ObjectId("604afee34b5860176c2254cf"),
"orderNo" : "3",
"customerNo" : "0003",
"orderLine" : [
{
"isbn" : "0001",
"price" : 341,
"amount" : 2
},
{
"isbn" : "0002",
"price" : 170.5,
"amount" : 1
},
{
"isbn" : "0003",
"price" : 190.5,
"amount" : 3
}
]
}
Output:
/* 1 */
{
"isbn" : "0001",
"amount_total" : 4
},
/* 2 */
{
"isbn" : "0002",
"amount_total" : 2
}
显然,这正是我想要的。
db.books.aggregate([
{
$lookup: {
from: "orders",
let: { isbn: "$isbn" }, // Pass this variable to pipeline for Joining condition.
pipeline: [
{ $unwind: "$orderLine" },
{
$match: {
// Join condition.
$expr: { $eq: ["$orderLine.isbn", "$$isbn"] }
}
},
{
$project: { _id: 0 , orderNo : 1, "orderLine.amount": 1}
}
],
as: "amount"
}
}, { $project : { _id : 0, isbn : 1, amount_total : { $sum : "$amount.orderLine.amount" } } }
])
$group
阶段中的$sum
将对根字段和分组字段求和,但这里orderLine
字段是一个数组,您需要在应用$sum
之前对该数组求和,这意味着嵌套的$sum
操作,
{
$group: {
_id: null,
amount_total: {
$sum: {
$sum: "$orderLine.amount"
}
}
}
}
尝试最终解决方案,
$in
条件在orderLine.isbn
中$match
isbn
数组$filter
迭代orderLine
数组的外观,并匹配isbn
,它将返回过滤后的文档$let
声明一个orders
变量来保存orderLine
的过滤文档,使用$sum
对过滤数组中的amount
求和$project
显示必填字段,并获取amount_total
数组的总和db.books.aggregate([
{
$lookup: {
from: "orders",
let: { isbn: "$isbn" },
pipeline: [
{ $match: { $expr: { $in: ["$$isbn", "$orderLine.isbn"] } } },
{
$project: {
_id: 0,
amount_total: {
$let: {
vars: {
orders: {
$filter: {
input: "$orderLine",
cond: { $eq: ["$$this.isbn", "$$isbn"] }
}
}
},
in: { $sum: "$$orders.amount" }
}
}
}
}
],
as: "amount"
}
},
{
$project: {
_id: 0,
isbn: 1,
amount_total: { $sum: "$amount.amount_total" }
}
}
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.