我有一个“订单”集合,如下所示:
{ typeID: 1, buyOrder: true, price: 100 },
{ typeID: 1, buyOrder: false, price: 120 },
{ typeID: 1, buyOrder: false, price: 130 },
{ typeID: 1, buyOrder: false, price: 250 },
{ typeID: 2, buyOrder: true, price: 500 },
{ typeID: 2, buyOrder: false, price: 610 },
{ typeID: 2, buyOrder: false, price: 690 },
{ typeID: 2, buyOrder: false, price: 590 }
我希望汇总这个系列并找到每个typeid的最佳买/卖价格。
结果应为:
{ typeID: 1, bestBuy: 100, bestSell: 120 }
{ typeID: 2, bestBuy: 500, bestSell: 610 }
定义bestBuy / bestSell
bestBuy = (buyOrder = true && max price)
bestSell = (buyOrder = false && min price)
这是我到目前为止所做的,但我知道这是错误的。有任何想法吗 ?
db.orders.aggregate([
{ $sort : { typeID : 1 }},
{ $group:
{ _id: { typeID : "$typeID", buyOrder : "$buyOrder"},
price: { $max: "$price" },
}
},
{ $project:
{ _id: 0,
typeID: "$_id.typeID",
price: "$price",
buyOrder: "$_id.buyOrder",
}
}
])
感谢您的时间。
答案 0 :(得分:3)
您可能还不知道$cond
运算符作为三元条件。所以基本上如果作为第一个参数给出的条件是true
,那么使用下一个参数中的值。如果条件的计算结果为false
,则使用运算符中最后一个条件中的值。
这证明是完美的,因为你已经有一个真或假的指标来确定字段
db.orders.aggregate([
{ "$project": {
"typeID": 1,
"bestBuy": { "$cond": [
"$buyOrder",
"$price",
null
]},
"bestSell": { "$cond": [
"$buyOrder",
null,
"$price"
]}
}},
{ "$group": {
"_id": "$typeID",
"bestBuy": { "$max": "$bestBuy" },
"bestSell": { "$min": "$bestSell" }
}},
{ "$sort": { "_id": 1 } }
])
答案 1 :(得分:0)
也许使用mapreduce你可以用这样的东西来实现这个目标:
var mapFunction1 = function() {
emit(this.typeID , this.buyOrder, this.price);
};
var reduceFunction1 = function(key, values) {
reducedValue = { bestBuy: 0, bestSell: 0 };
for (var idx = 0; idx < values.length; idx++) {
if(values[idx].buyOrder && reducedValue.bestBuy < values[idx].price) {
reducedValue.bestBuy = values[idx].price
}
if(!values[idx].buyOrder && reducedValue.bestSell > values[idx].price) {
reducedValue.bestSell = values[idx].price
}
}
return reducedValue;
};
db.orders.mapReduce(
mapFunction1,
reduceFunction1,
{ out: "your_result" }
)
希望有所帮助