我收集了以下条目:
{
company:"C3",
model:"M3",
price:55600,
discount:9,
...
}
并且有超过2000个条目。
我正在尝试找出整个系列中
max
和 min
的价格。
也许有类似的东西:
db.collection.find({ max: { $max: "$price" }, min: { $min: "$price" } });
我希望输出为
{ max: 2000, min: 5000 }
。
.aggregate()
方法才能发挥作用。
db.collection.aggregate([
{ "$group": {
"_id": null,
"max": { "$max": "$price" },
"min": { "$min": "$price" }
}}
])
_id
字段在$group
阶段是强制性的,要查找整个集合而不是特殊组的max
/min
价格值,需要将其设置为null 否则查询将返回多个最大/最小结果,每组一个结果
$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
阶段,该阶段仅保留第一个项目(由所选顺序定义的最小项目)。管道的第二部分( /
$first
阶段)只是将 $facet
输出清理为您想要的格式。
$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] } } }