我想了解这是如何运作的:
我收集了这样的数据:
{ _id: 5a854ee830093123a44bb7ec,
item: 124103,
owner: 'ZZZ',
quantity: 50, //between 1 and X (X is fixed and I determine it before, in this case it's 50)
lastModified: 1518685663000, //there are various lastModified intraday
price: 116000,
date: 2018-02-15 17:28:04.332 //default: new Date().toISOString()
}
和聚合脚本:
x.aggregate([
{
$project: { year: { $year: "$date" },
month: { $month: "$date" },
day: { $dayOfMonth: "$date" },
item: "$item",
owner: "$owner",
quantity: "$quantity",
lastModified: "$lastModified",
price: "$price"}
},
{
$match: { item: 124103, day: 15, month: 2, year: 2018, lastModified: 1518685663000}
},
//and here I use my group stage
{
$group:
{
_id: "$item",
min_1: { $cond: { if: { $eq: [ "$quantity", 1] }, then: { $min: "$price" } } },
min_X: { $cond: { if: { $eq: [ "$quantity", X(50)] }, then: { $min: "$price" } } },
// then same for $max and $avg, (with different quantities) etc
},
},callback
我想收到什么:
在min_X
字段中我希望仅在$min:$price
等于X值(50)时才会收到quantity
。
实际上我可以通过许多查询接收必要的数据(我实际上现在正在做)但我猜StackOverflow社区的人们知道如何通过$ match和$ unwind的1个查询来实现相同的结果。
是的,我已经阅读了文档,但只了解我应该是$cond
运营商。猜猜有人可以带我到这里,并提供相关的例子。例如,将来我希望在不同的$lastModified
日内操作,这意味着,我希望在$project
阶段之后对数据进行分组,然后展开光标和$将其与另一个$lastModified
分组。
答案 0 :(得分:1)
它是$min
的另一种方式,然后是$cond
。
$group需要其中一个accumulators用于分组字段。在您的情况下,它是$min
。然后,您可以应用条件$cond
哪个值用于聚合。如果是$min
,您可以将Number.MAX_VALUE
用于与条件不符的文档。它总是大于或等于javascript中的任何其他值。你可以在这里自由使用任何明智的常数。
之后你可能想要通过在另一个投影阶段用空值替换垃圾数来清理它:
x.aggregate([
.....
{ $group: {
_id: "$item",
min_1: { $min: { $cond: [ { $eq: [ "$quantity", 1] }, "$price", Number.MAX_VALUE ] } },
min_50: { $min: { $cond: [ { $eq: [ "$quantity", 50] }, "$price", Number.MAX_VALUE ] } }
// then same for $max and $avg, (with different quantities) etc
} },
{ $project: {
min_1: { $cond: [ { $eq: [ "$min_1", Number.MAX_VALUE] }, null, "$min_1" ] },
min_50: { $cond: [ { $eq: [ "$min_50", Number.MAX_VALUE] }, null, "$min_50" ] }
} }
])