2017-06-23 94 views
0

模式是:計數文檔匹配多個陣列標準

{ 
"_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); 

我知道我做錯了,因爲我越來越算作1,當我查詢用戶參考ID hello和statusList與作爲UNREAD單個元素。

如何對數組元素執行聚合查詢?

+0

嗯是的「查詢」是不正確的,但是,從你的問題,你也不清楚你想在這裏「計數」的事情。 A.匹配的文檔B.匹配的'「sendTo」'中的項目總數,或者C.匹配兩個條件的所有'「mediumAndDestination」'中的項目總數?因此,您樣本中的文檔** none **與條件組合相匹配,但也不清楚這是否基本上是您要求的。 –

+0

@NeilLunn說,我想統計一個用戶通知是'UNREAD'。用戶由'userReferenceId'標識,通知狀態由'status'標識。 –

+0

我列表中的A,B或C中哪一個是「用戶通知」?是「A」文件嗎?你是否期待'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就是這個樣。

+0

這工作。很好的解釋,特別是'本質上序列化'部分。 –

+0

@ShubhamA。這是'elemMatch'部分,您需要學習如何使用**數組中的元素的**條件。沒有這個,你實際上正在查看** ALL **提供的字段路徑的數組值。這是查詢中的差異。所以我們只是比較「一次一個元素」。你可以使用'.getCriteriaObject()'從任何'Criteria'獲得JSON序列化。很適合比較。此外,如果你「發現它有幫助」,那麼[我認爲在這裏有一個動作。](https://meta.stackexchange.com/questions/173399/how-to-upvote-on-stack-overflow) –