Mongodb 如何聚合集合并查找最小/最大值

Mongodb 如何聚合集合并查找最小/最大值,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个“订单”集合,如下所示: { 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, bu

我有一个“订单”集合,如下所示:

{ 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  = (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",
         }
     }
    ])

谢谢您的时间。

也许使用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" }
)
var mapFunction1=function(){
发出(this.typeID、this.buyOrder、this.price);
};
var reduceFunction1=函数(键、值){
reducedValue={bestBuy:0,bestSell:0};
对于(var idx=0;idxvalues[idx].price){
reducedValue.bestSell=值[idx]。价格
}
}
返回还原值;
};
db.orders.mapReduce(
地图功能1,
还原函数1,
{out:“你的结果”}
)

希望它有帮助

您可能还没有意识到作为三元条件工作的运算符。因此,基本上,如果作为第一个参数给定的条件是
true
,则在下一个参数中使用该值。如果条件的计算结果为
false
,则使用运算符中最后一个条件中的值

事实证明,这是完美的,因为您已经有了一个判断字段为真或假的指示器

db.orders.aggregate([
{“$project”:{
“类型ID”:1,
“百思买”:{“$cond”:[
“$buyOrder”,
“$price”,
无效的
]},
“最佳销售”:{“$cond”:[
“$buyOrder”,
无效的
“$price”
]}
}},
{“$组”:{
“_id”:“$typeID”,
“百思买”:{“$max”:“$bestBuy”},
“最佳销售”:{“$min”:“$bestSell”}
}},
{“$sort”:{“\u id”:1}
])

因此,在不满足条件的情况下,在此处使用and可以否定结果中的
null
值。

如何定义bestBuy和bestSell?忘了提及这一点
bestBuy=(buyOrder=true&max price)
对于
bestSell=(buyOrder=false&min price)
您将获得聚合框架的最佳参考,您确实应该学习。除了本机代码方法的运行速度比
mapReduce
快得多这一事实之外,这个答案还有一个普遍的缺陷,即处理“大型”数组需要付出相当大的成本。有更有效的方法可以从数组中获取“max”或“min”值。同样,在映射器中也可以应用类似的三元。看我的答案,里面也有链接。我同意尼尔的观点。在这里提问之前,我使用了mapReduce,我的工作在120秒内完成。对于聚集fw和Neil,其解小于20秒。谢谢这太完美了。我不知道,
$cond
!非常感谢!:)