问题
Documents:
[
{
name: 'abc'
length: 25,
area: 10
},
{
name: 'abc',
length: 5
}
]
Output after aggregate query:
[
{
count: 2,
summarizedLength: 30,
summarizedArea: null,
_id: {
name: 'abc'
}
}
]
The length and area should summarized. But only if all documents have the area or length property.
So if any length property is missing by the grouped properties, the summarizedLength value should be null/undefined/not exisitng, and same with area.
I tried this:
let query = mongoose.model('mycollection').aggregate([
{
$group: {
_id: {
name: $name
},
count: {
$sum: 1
},
summarizedLength: { $sum: "$length" },
summarizedArea: { $sum: "$area" },
}
}
]);
Problem is, I need to cancel the $sum if any property is missing. Is this possible?
回答1:
From the Mongo documentation $sum behavior
If used on a field that contains both numeric and non-numeric values, $sum ignores the non-numeric values and returns the sum of the numeric values.
If used on a field that does not exist in any document in the collection, $sum returns 0 for that field.
If all operands are non-numeric, $sum returns 0.
we can $push all area and length to array, and compare count with the length of array
db.n.aggregate(
[
{
$group: {
_id: { name: "$name" },
count: { $sum: 1 },
area : {$push : "$area"},
length : {$push : "$length"} }
},
{
$project:{
_id: "$_id",
count: "$count",
summarizedLength: { $cond : [ {$eq : [ "$count", {$size : "$length"} ]} , { $sum : ["$length"] }, "not all numbers" ] },
summarizedArea: { $cond : [ {$eq : [ "$count", {$size : "$area"} ]} , { $sum : ["$area"] }, "not all numbers" ] },
}
}
]
)
or, we can count the number of defined length and area, along with total count, if counts matching then all numbers else some undefined.
To strictly check the type, in case if area and length may contain non numeric data, instead of undefined we can do $type check
db.n.aggregate(
[
{
$group: {
_id: { name: "$name" },
count: { $sum: 1 },
areaCount : { $sum : { $cond : [ {$eq : [ "$area", undefined ]} , 0, 1 ] } },
lengthCount : { $sum : { $cond : [ {$eq : [ "$length", undefined ]} , 0, 1 ] } },
summarizedLength: { $sum: "$length" },
summarizedArea: { $sum: "$area" }
}
},
{
$project : {
_id : "$_id",
count: "$count",
summarizedLength: { $cond : [ {$eq : [ "$count", "$lengthCount" ]} , "$summarizedLength", "not all numbers" ] },
summarizedArea: { $cond : [ {$eq : [ "$count", "$areaCount" ]} , "$summarizedArea", "not all numbers" ] },
}
}
]
).pretty()
output
{
"_id" : {
"name" : "abc"
},
"count" : 2,
"summarizedLength" : 30,
"summarizedArea" : "not all numbers"
}
来源:https://stackoverflow.com/questions/48235279/mongodb-sum-with-condition