我有一个像这样的聚合查询:
db.yc_promotions.aggregate([
{$match:
{
city_from: {$in: ['x1','x2','x3']},
city_to: {$in: ['y1','y2','y3']},
date_ret: {$lte: "2013-06-30"},
updated: {"$gte": "2013-02-01"}
}
},
{$group:
{
_id: {city_to: "$city_to"},
min: { $min: "$total_price" }
}
}
])
查询响应如下所示:
{"result" : [
{
"_id" : {
"city_to" : "y1"
},
"min" : 2404.72
},
{
"_id" : {
"city_to" : "y2"
},
"min" : 1619.2
}
...
]}
但我希望以最低价格而不仅仅是价值和城市代码返回对象。我该怎么做?
谢谢!
答案 0 :(得分:4)
看起来您应该可以使用以下内容添加其他字段(我忽略了匹配):
db.test.aggregate(
{ $group: {
_id: { city_to: "$city_to" },
min: { $min: "$total_price" },
city_from: { $min: "$city_from" }
} }
);
但这不起作用。 $ min将用于每个字段。举个例子:
> db.test.find();
{ "_id" : ObjectId("51156a11056d6f966f268f7f"), "city_from" : "LHR", "city_to" : "JFK", "total_price" : 500 }
{ "_id" : ObjectId("51156a1a056d6f966f268f80"), "city_from" : "LHR", "city_to" : "LGA", "total_price" : 400 }
{ "_id" : ObjectId("51156a1e056d6f966f268f81"), "city_from" : "DUB", "city_to" : "LGA", "total_price" : 400 }
{ "_id" : ObjectId("51156a27056d6f966f268f82"), "city_from" : "DUB", "city_to" : "JFK", "total_price" : 300 }
> db.test.aggregate( {$group: { _id: { city_to: "$city_to" }, min: { $min: "$total_price" }, city_from: { $min: "$city_from" } } } );
{
"result" : [
{
"_id" : {
"city_to" : "LGA"
},
"min" : 400,
"city_from" : "DUB"
},
{
"_id" : {
"city_to" : "JFK"
},
"min" : 300,
"city_from" : "DUB"
}
],
"ok" : 1
}
city_from:LHR 完全消失,即使LHR-> LGA和DUB-> LGA都具有相同的最低价格。 city_from:{$ min:“$ city_from”} 仅返回[DUB,LGA]的字符串最小值。您当然可以拥有多个具有相同最低价格的文档(在这种情况下,对于LHR-> LGA和DUB-> LGA都是400个。)
您必须分两步完成此操作:
> result = db.test.aggregate( {$group: { _id: { city_to: "$city_to" }, min: { $min: "$total_price" } } } );
> final = []
> result.result.forEach(function(entry) { final.push( { city_to: entry._id.city_to, min: entry.min, docs: db.test.aggregate( { $match: { city_to: entry._id.city_to, total_price: entry.min } } ).result } ) } );
然后给出结果:
> final
[
{
"city_to" : "LGA",
"min" : 400,
"docs" : [
{
"_id" : ObjectId("51156a1a056d6f966f268f80"),
"city_from" : "LHR",
"city_to" : "LGA",
"total_price" : 400
},
{
"_id" : ObjectId("51156a1e056d6f966f268f81"),
"city_from" : "DUB",
"city_to" : "LGA",
"total_price" : 400
}
]
},
{
"city_to" : "JFK",
"min" : 300,
"docs" : [
{
"_id" : ObjectId("51156a27056d6f966f268f82"),
"city_from" : "DUB",
"city_to" : "JFK",
"total_price" : 300
}
]
}
]
答案 1 :(得分:1)
当你分组时,你必须告诉MongoDB你想要的其他字段的值。所以你在哪里:
min: { $min: "$total_price" }
您需要复制此字段并为要返回的投影对象的每个字段重命名,在这种情况下:
city_to: { $min: "$city_to" },
city_from: { $min: "$city_from" }
// etc
所以一个完整的例子是:
db.yc_promotions.aggregate([
{$match:
{
city_from: {$in: ['x1','x2','x3']},
city_to: {$in: ['y1','y2','y3']},
date_ret: {$lte: "2013-06-30"},
updated: {"$gte": "2013-02-01"}
}
},
{$group:
{
_id: {city_to: "$city_to"},
min: { $min: "$total_price" },
city_to: { $min: "$city_to" },
city_from: { $min: "$city_from" }
}
}
])
了解我如何将city_to
和city_from
添加到$group
?只需为您希望在$group
中投射的每个字段执行此操作。