问题
I have following offers
collection
Here readBy
contains the _id
of the users...
Now I want to count the number of unRead offers for the userId = "5add82620d7f5b38240c63d4"
{
"_id" : ObjectId("5aeaab5ed6a9c97d0209260a"),
"expiresIn" : ISODate("2018-05-30T18:30:00.000Z"),
"name" : "Trip ",
"readBy" : [
ObjectId("5add82620d7f5b38240c63d4"),
ObjectId("5add82620d7f5b38240c63c6")
],
"__v" : 0
}
{
"_id" : ObjectId("5aeaab7dd6a9c97d0209260b"),
"expiresIn" : ISODate("2018-05-29T18:30:00.000Z"),
"name" : "Trip",
"readBy" : [ObjectId("5add82620d7f5b38240c63d4")],
"__v" : 0
}
{
"_id" : ObjectId("5aeae233d6a9c97d02092622"),
"expiresIn" : ISODate("2018-05-25T18:30:00.000Z"),
"name" : "two way off",
"readBy" : [],
}
{
"_id" : ObjectId("5aeae49643f10d284726069c"),
"expiresIn" : ISODate("2018-05-25T18:30:00.000Z"),
"name" : "two way off",
"readBy" : [],
}
{
"_id" : ObjectId("5aeae49743f10d284726069d"),
"expiresIn" : ISODate("2018-05-25T18:30:00.000Z"),
"name" : "two way off",
"readBy" : []
}
{
"_id" : ObjectId("5aeae49743f10d284726069e"),
"expiresIn" : ISODate("2018-05-25T18:30:00.000Z"),
"name" : "two way off",
"readBy" : []
}
so for the above collection my output should be
[{
numberOfUnreadOffers: 4
}]
because four of the collection does not have 5add82620d7f5b38240c63d4
in readBy
array
回答1:
You basically use $setIsSubset and $cond here:
var userId= "5add82620d7f5b38240c63d4";
Model.aggregate([
{ "$group": {
"_id": null,
"numberOfUnreadOffers": {
"$sum": {
"$cond": {
"if": {
"$setIsSubset": [[mongoose.Types.ObjectId(userId)], "$readBy"]
},
"then": 0,
"else": 1
}
}
}
}}
])
Of course you also need to "cast" using mongoose.Types.ObjectId
from the "string" to a valid ObjectId
value.
But really you get better performance from a simple count() instead:
Model.count({ "readBy": { "$ne": userId } })
So you really should not use .aggregate()
for this at all.
来源:https://stackoverflow.com/questions/50210367/count-where-value-does-not-match-array