计算匹配多个阵列标准的文档

时间:2017-06-23 06:31:08

标签: spring mongodb mongodb-query spring-mongodb

架构是:

{ 
"_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。

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

1 个答案:

答案 0 :(得分:1)

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

   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"唯一匹配的内容实际上是"status" "READ"。如果我改为提供这些标准:

  { 
    "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