问题
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