我正在尝试构建一个管道,它将根据某些标准搜索文档,并将某些字段分组以提供所需的输出。 deals
的文件结构是
{
"_id":"123",
"status":"New",
"deal_amount":"5200",
"deal_date":"2018-03-05",
"data_source":"API",
"deal_type":"New Business",
"account_id":"A1"
},
{
"_id":"456",
"status":"New",
"deal_amount":"770",
"deal_date":"2018-02-11",
"data_source":"API",
"deal_type":"New Business",
"account_id":"A2"
},
{
"_id":"885",
"status":"Old",
"deal_amount":"4070",
"deal_date":"2017-09-22",
"data_source":"API",
"deal_type":"New Business",
"account_id":"A2"
},
帐户名称是引用字段。帐户文件是这样的:
{
"_id":"A1",
"name":"Sarah",
},
{
"_id":"A2",
"name":"Amber",
},
管道应该搜索“状态”为“新”且“交易金额”超过2000的文档,并且应按“帐户名”分组。我用过的管道是这样的
db.deal.aggregate([{
$match: {
status: New,
deal_amount: {
$gte: 2000,
}
}
}, {
$group: {
_id: "$account_name",
}
},{
$lookup:{
from:"accounts",
localField:"account_id",
foreignField:"_id",
as:"acc",
}
}
])
我想仅在结果中显示字段deal_amount,deal_type,deal_date和帐户名称。
预期结果:
{
"_id": "123",
"deal_amount": "5200",
"deal_date": "2018-03-05",
"deal_type": "New Business",
"account_name": "Sarah"
}, {
"_id": "885",
"deal_amount": "4070",
"deal_date": "2017-09-22",
"deal_type": "New Business",
"account_name": "Amber"
},
我是否必须在“组”阶段中包含所有这些字段,deal_amount,deal_type,deal_date和帐户名称才能显示结果,或者是否有其他方法可以执行此操作。任何帮助都非常感谢。
不知道为什么你需要$group
阶段。您只需添加$project
阶段即可从引用的集合中输出帐户名称。
{
"$project": {
"deal_amount": 1,
"deal_type": 1,
"deal_date": 1,
"account_name": {"$let":{"vars":{"accl":{"$arrayElemAt":["$acc", 0]}}, in:"$$accl.name}}
}
}
请使用此查询。
aggregate([{
$match: {
status: "New",
deal_amount: {
$gte: 2000,
}
}
},
{
$lookup:{
from:"accounts",
localField:"account_id",
foreignField:"_id",
as:"acc",
}
},
{
$unwind: {
path: '$acc',
preserveNullAndEmptyArrays: true,
},
},
{
$group: {
_id: "$acc._id",
deal_amount: { $first: '$deal_amount' },
deal_date: { $first: '$deal_date' },
deal_type: { $first: '$deal_type' },
}
}
])
你可以做:
1)使用$$ ROOT参考:link
{ $group : {
_id : "$author",
data: { $push : "$$ROOT" }
}}
2)通过分配单个参数
{
$group: {
_id: "$account_name",
deal_amount: { $first: '$deal_amount' },
deal_date: { $first: '$deal_date' },
.
.
}
}
首先,你的$gte
运算符不适用于字符串字段deal_amount
,所以你可能想要将字段更改为整数或类似的东西:
// Convert String to Integer
db.deals.find().forEach(function(data) {
db.deals.update(
{_id:data._id},
{$set:{deal_amount:parseInt(data.deal_amount)}});
然后,要获得所需的字段,请使用$project
重新整理文档:
db.deals.aggregate([{
$match: {
"status": "New",
"deal_amount" : {
"$gte" : 2000
}
}
},
{
$lookup:{
from:"accounts",
localField:"account_id",
foreignField:"_id",
as:"acc",
}
},
{
$project: {
_id: 1,
deal_amount: 1,
deal_type: 1,
deal_date: 1,
"account_name": {"$let":{"vars":{"accl":{"$arrayElemAt":["$acc", 0]}}, in:"$$accl.name"}}
}
}
]);
对我来说,这产生了:
{
"_id" : "123",
"deal_amount" : 5200.0,
"deal_date" : "2018-03-05",
"deal_type" : "New Business",
"account_name" : "Sarah"
}