有没有办法从 MongoDB 中的查询中 return 特定的嵌套字段?
Is there a way to return specific nested fields from a query in MongoDB?
有没有办法获得每个运动类别支付的金额?
不能只限于"John,",而是在所有的集合文档中。
预期查询 return 提供的数据:
{
{"Fight": [100,95] },
{"Running": [50] }
}
数据示例:
{"_id":"5z621578b0ce483b9866fb1f",
"Name":"John",
"Sports":[
{"Category":"Fight",
"Billing":[
{"Month":"Jan",
"Status":"Paid",
"Price":100},
{"Month":"Feb",
"Status":"Not Paid",
"Price":125},
{"Month":"Mar",
"Status":"Paid",
"Price":95}
]
},
{"Category":"Running",
"Billing":[
{"Month":"Jan",
"Status":"Not Paid",
"Price":200},
{"Month":"Feb",
"Status":"Paid",
"Price":50}
]
}
]
}
换句话说:我需要比较每个嵌套对象中的账单状态并检查它是否"Paid",然后如果为真,则将各自的计费对象价格 添加到各自的运动类别 数组。
对于集合中的所有文档,具有多个运动类别和多个计费月份。但总是相同的嵌套结构。
提前致谢!
正如 willis 在他的评论中所说,您需要使用聚合:https://docs.mongodb.com/manual/aggregation/
以下聚合将为您提供您正在寻找的数据(将 billings 替换为您收集的实际名称):
db.billings.aggregate([
{ $unwind: '$Sports'},
{ $unwind: '$Sports.Billing'},
{ $match: { 'Sports.Billing.Status': 'Paid' } },
{
$group: {
_id: '$Sports.Category',
Category: {$first: '$Sports.Category'},
Prices: { $push: '$Sports.Billing.Price' }
}
},
{ $project: {_id: 0} }
]);
此聚合的结果将如下所示:
[
{
"Category" : "Running",
"Prices" : [
50.0
]
},
{
"Category" : "Fight",
"Prices" : [
100.0,
95.0
]
}
]
你问题中要求的具体格式有点不正常;在我看来,我认为最好将其保持在输出之上的聚合形式。但是如果你想要它的形式像你问题中的那样,聚合有点复杂:
db.billings.aggregate([
{ $unwind: '$Sports'},
{ $unwind: '$Sports.Billing'},
{ $match: { 'Sports.Billing.Status': 'Paid' } },
{
$group: {
_id: '$Sports.Category',
Prices: { $push: '$Sports.Billing.Price' }
}
},
{
$group: {
_id: 0,
Sports: { $push: { Category: '$_id', Prices: '$Prices' } }
}
},
{
$project: {
Sports: {
$arrayToObject: {
'$map': {
'input': '$Sports',
'as': 'el',
'in': {
'k': '$$el.Category',
'v': '$$el.Prices'
}
}
}
}
}
},
{ $replaceRoot: { newRoot: '$Sports'} }
]);
有没有办法获得每个运动类别支付的金额? 不能只限于"John,",而是在所有的集合文档中。
预期查询 return 提供的数据:
{
{"Fight": [100,95] },
{"Running": [50] }
}
数据示例:
{"_id":"5z621578b0ce483b9866fb1f",
"Name":"John",
"Sports":[
{"Category":"Fight",
"Billing":[
{"Month":"Jan",
"Status":"Paid",
"Price":100},
{"Month":"Feb",
"Status":"Not Paid",
"Price":125},
{"Month":"Mar",
"Status":"Paid",
"Price":95}
]
},
{"Category":"Running",
"Billing":[
{"Month":"Jan",
"Status":"Not Paid",
"Price":200},
{"Month":"Feb",
"Status":"Paid",
"Price":50}
]
}
]
}
换句话说:我需要比较每个嵌套对象中的账单状态并检查它是否"Paid",然后如果为真,则将各自的计费对象价格 添加到各自的运动类别 数组。
对于集合中的所有文档,具有多个运动类别和多个计费月份。但总是相同的嵌套结构。
提前致谢!
正如 willis 在他的评论中所说,您需要使用聚合:https://docs.mongodb.com/manual/aggregation/
以下聚合将为您提供您正在寻找的数据(将 billings 替换为您收集的实际名称):
db.billings.aggregate([
{ $unwind: '$Sports'},
{ $unwind: '$Sports.Billing'},
{ $match: { 'Sports.Billing.Status': 'Paid' } },
{
$group: {
_id: '$Sports.Category',
Category: {$first: '$Sports.Category'},
Prices: { $push: '$Sports.Billing.Price' }
}
},
{ $project: {_id: 0} }
]);
此聚合的结果将如下所示:
[
{
"Category" : "Running",
"Prices" : [
50.0
]
},
{
"Category" : "Fight",
"Prices" : [
100.0,
95.0
]
}
]
你问题中要求的具体格式有点不正常;在我看来,我认为最好将其保持在输出之上的聚合形式。但是如果你想要它的形式像你问题中的那样,聚合有点复杂:
db.billings.aggregate([
{ $unwind: '$Sports'},
{ $unwind: '$Sports.Billing'},
{ $match: { 'Sports.Billing.Status': 'Paid' } },
{
$group: {
_id: '$Sports.Category',
Prices: { $push: '$Sports.Billing.Price' }
}
},
{
$group: {
_id: 0,
Sports: { $push: { Category: '$_id', Prices: '$Prices' } }
}
},
{
$project: {
Sports: {
$arrayToObject: {
'$map': {
'input': '$Sports',
'as': 'el',
'in': {
'k': '$$el.Category',
'v': '$$el.Prices'
}
}
}
}
}
},
{ $replaceRoot: { newRoot: '$Sports'} }
]);