我有以下offers收藏

这里readBy包含用户的_id ...
现在,我要计算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" : []
}


所以对于上面的集合,我的输出应该是

[{
  numberOfUnreadOffers: 4
}]


因为集合的四个在5add82620d7f5b38240c63d4数组中没有readBy

最佳答案

您基本上在这里使用$setIsSubset$cond

var userId= "5add82620d7f5b38240c63d4";

Model.aggregate([
  { "$group": {
    "_id": null,
    "numberOfUnreadOffers": {
      "$sum": {
        "$cond": {
          "if": {
            "$setIsSubset": [[mongoose.Types.ObjectId(userId)], "$readBy"]
          },
          "then": 0,
          "else": 1
        }
      }
    }
  }}
])


当然,您还需要使用mongoose.Types.ObjectId从“字符串”“广播”到有效的ObjectId值。

但是实际上,您可以通过简单的count()来获得更好的性能:

Model.count({ "readBy": { "$ne": userId } })


因此,您实际上根本不应该使用.aggregate()

关于node.js - 计算值与数组不匹配的地方,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50210367/

10-11 12:57