mongodb 中的最大值和最小值

问题描述 投票:0回答:2

我收集了以下条目:

{
  company:"C3",
  model:"M3",
  price:55600,
  discount:9,
  ...
}

并且有超过2000个条目。

我正在尝试找出整个系列中

max
min
的价格。

也许有类似的东西:

db.collection.find({ max: { $max: "$price" }, min: { $min: "$price" } });

我希望输出为

{ max: 2000, min: 5000 }

mongodb mongodb-query aggregation-framework min
2个回答
31
投票

您需要使用

.aggregate()
方法才能发挥作用。

db.collection.aggregate([ 
    { "$group": { 
        "_id": null,
        "max": { "$max": "$price" }, 
        "min": { "$min": "$price" } 
    }}
])

_id
字段在
$group
阶段是强制性的,要查找整个集合而不是特殊组的
max
/
min
价格值,需要将其设置为null 否则查询将返回多个最大/最小结果,每组一个结果


3
投票

您可以使用

$facet
阶段,与
$sort
/
$limit
阶段相结合:

// { "price": 123 }
// { "price": 165 }
// { "price": 98  }
// { "price": 34  }
db.collection.aggregate([
  { $facet: {
    min: [{ $sort: { price:  1 } }, { $limit: 1 }],
    max: [{ $sort: { price: -1 } }, { $limit: 1 }]
  }},
  { $project: { min: { $first: "$min.price" }, max: { $first: "$max.price" } } }
])
// { "min" : 34, "max" : 165 }

$facet
阶段允许我们在单个阶段内对同一组输入文档运行多个聚合管道。每个子管道在输出文档中都有自己的字段,其结果存储为文档数组。

因此,每个字段都是由其自己的聚合管道生成的,其第一阶段

$sort

 按指定的顺序显示价格,然后是 
$limit
 阶段,该阶段仅保留第一个项目(由所选顺序定义的最小项目)。 

管道的第二部分(

$project

 / $first
阶段)只是将 
$facet
 输出清理为您想要的格式。


请注意,Mongo 优化了

$sort

 后跟的 
$limit
 阶段(参见 
here)。这允许排序操作在进行时仅保留前 n 个结果(在我们的例子中仅保留 1 个元素)。

另请注意,我们的

$sort

 阶段将受益于 
price
 上的索引。

如果您使用旧版本的 MongoDB,

$first

 可能会导致

{ "ok" : 0.0, "errmsg" : "Unrecognized expression '$first'", "code" : 168.0, "codeName" : "InvalidPipelineOperator" }
您也许可以使用 

$project

 而不是 
$arrayElemAt
$first
(或者完全跳过 
$project
,它只是为了格式化结果)

// could use for older versions of MongoDB: { $project: { min: { $arrayElemAt: ["$min.processingStartTime", 0] }, max: { $arrayElemAt: ["$max.processingEndTime", 0] } } }
    
© www.soinside.com 2019 - 2024. All rights reserved.