对匹配多个数组条件的文档进行计数

Count Documents Matching Multiple Array Criteria

架构是:

{ 
"_id" : ObjectId("594b7e86f59ccd05bb8a90b5"), 
"_class" : "com.notification.model.entity.Notification", 
"notificationReferenceId" : "7917a5365ba246d1bb3664092c59032a", 
"notificationReceivedAt" : ISODate("2017-06-22T08:23:34.382+0000"), 
"sendTo" : [
    {
        "userReferenceId" : "check", 
        "mediumAndDestination" : [
            {
                "medium" : "API",
                "status" : "UNREAD"
            }
        ]
    }
]
}
{ 
"_id" : ObjectId("594b8045f59ccd076dd86063"), 
"_class" : "com.notification.model.entity.Notification", 
"notificationReferenceId" : "6990329330294cbc950ef2b38f6d1a4f",
"notificationReceivedAt" : ISODate("2017-06-22T08:31:01.299+0000"), 
"sendTo" : [
    {
        "userReferenceId" : "check",
        "mediumAndDestination" : [
            {
                "medium" : "API",
                "status" : "UNREAD"
            }
        ]
    }
]
}
{ 
"_id" : ObjectId("594b813ef59ccd076dd86064"), 
"_class" : "com.notification.model.entity.Notification", 
"notificationReferenceId" : "3c910cf5fcec42d6bfb78a9baa393efa", 
"notificationReceivedAt" : ISODate("2017-06-22T08:35:10.474+0000"), 
"sendTo" : [
    {
        "userReferenceId" : "check", 
        "mediumAndDestination" : [
            {
                "medium" : "API", 
                "status" : "UNREAD"
            }
        ]
    }, 
    {
        "userReferenceId" : "hello", 
        "mediumAndDestination" : [
            {
                "medium" : "API",
                "status" : "READ"
            }
        ]
    }
]
}

我想计算 个基于 statusList 的用户通知,它是 List。我使用 mongoOperations 进行查询:

Query query = new Query();
    query.addCriteria(Criteria.where("sendTo.userReferenceId").is(userReferenceId)
    .andOperator(Criteria.where("sendTo.mediumAndDestination.status").in(statusList)));

long count = mongoOperations.count(query, Notification.class);

我意识到我做错了,因为当我查询具有参考 ID hello 的用户和具有单个元素 UNREAD.

的 statusList 时,我被计为 1

如何对数组元素执行聚合查询?

查询需要 $elemMatch 才能实际匹配 "within" 符合两个条件的数组元素:

   Query query = new Query(Criteria.where("sendTo")
       .elemMatch(
           Criteria.where("userReferenceId").is("hello")
             .and("mediumAndDestination.status").is("UNREAD")
       ));

本质上序列化为:

  { 
    "sendTo": {
      "$elemMatch": {
        "userReferenceId": "hello",
        "mediumAndDestination.status": "UNREAD"
      }
    }
  }

请注意,在您的问题中没有这样的文档,唯一与 "hello" 匹配的实际上是 "READ""status"。如果我改为提供这些标准:

  { 
    "sendTo": {
      "$elemMatch": {
        "userReferenceId": "hello",
        "mediumAndDestination.status": "READ"
      }
    }
  }

然后我得到最后一个文档:

{
    "_id" : ObjectId("594b813ef59ccd076dd86064"),
    "_class" : "com.notification.model.entity.Notification",
    "notificationReferenceId" : "3c910cf5fcec42d6bfb78a9baa393efa",
    "notificationReceivedAt" : ISODate("2017-06-22T08:35:10.474Z"),
    "sendTo" : [ 
        {
            "userReferenceId" : "check",
            "mediumAndDestination" : [ 
                {
                    "medium" : "API",
                    "status" : "UNREAD"
                }
            ]
        }, 
        {
            "userReferenceId" : "hello",
            "mediumAndDestination" : [ 
                {
                    "medium" : "API",
                    "status" : "READ"
                }
            ]
        }
    ]
}

但对于 "UNREAD",此样本的计数实际上是 0