2016-01-11 91 views
1

蒙戈的java我有以下結構查找和upserting嵌套數組元素

{ 
    "_id" : ObjectId("568eaba5e4b0fa3cdf9aaf85"), 
    "type" : "X", 
    "textId" : "568eaba5e4b0fa3cdf9aaf84", 
    "createDate" : "2016-01-07 18:17:09", 
    "likes" : [ 
     { 
      "creatorName" : "ABCD", 
      "creationDate" : "2016-01-10 19:48:37", 
      "likeId" : "56932615569aae9d1459eb9b" 
     } 
    ] 
} 

我需要的是如下一蒙戈集合元素: 當一個新的希望由creatorName發佈特定元素由textId標識,我應該 a)檢查特定的textId對象的creatorName是否已經存在。如果存在,什麼都不做 b)如果類似的不存在,我應該在喜歡的數組中插入一個新的元素

如何在java中有效地做到這一點?我看到我們有一個更新方法和一個findAndModify方法。哪一個使用以及如何以最有效的方式處理這個問題?

回答

1

Unique indexes

如下您可以創建唯一索引:

db.collection.createIndex({ "likes.creatorName": 1 }, { unique: true }) 

官方文件說:

唯一索引導致的MongoDB拒絕那些包含的所有文件 索引字段的重複值。

如果creatorName已經存在,寫操作將如下失敗:

WriteResult({ 
    "nInserted" : 0, 
    "writeError" : { 
     "code" : 11000, 
     "errmsg" : "E11000 duplicate key error index: test.collection.$likes.creatorName_1 dup key: { : 1.0 }" 
    } 
}) 

然後,你不必擔心,如果creatorName已經存在。另一方面,如果您需要知道creatorName是否已經存在,則需要查看WriteResult返回的值(0或1)。

0

您可以通過update功能與查詢條件插入喜歡:


db.collection.update({ 
    "textId" : "568eaba5e4b0fa3cdf9aaf84", 
    "likes.likeId": {"$nin": ["56932615569aae9d1459eb10"]}, 
    "likes.creatorName" : {"$nin": ["ABCE"]} 
    }, 
    { 
     "$push" : { 
      "likes" : { 
       "creatorName" : "ABCE", 
       "creationDate" : "2016-01-10 21:48:37", 
       "likeId" : "56932615569aae9d1459eb10" 
      } 
     } 
    } 
) 

Updated 1 existing record(s) 

如果您嘗試添加新的像一樣creatorName,也不會更新。

db.collection.update({ 
    "textId" : "568eaba5e4b0fa3cdf9aaf84", 
    "likes.likeId": {"$nin": ["56932615569aae9d1459eb11"]}, 
    "likes.creatorName" : {"$nin": ["ABCD"]} 
    }, 
    { 
     "$push" : { 
      "likes" : { 
       "creatorName" : "ABCD", 
       "creationDate" : "2016-01-11 19:48:37", 
       "likeId" : "56932615569aae9d1459eb11" 
      } 
     } 
    } 
) 

Updated 0 record(s) 

Java驅動程序沒有提供任何性能優勢。

如果根據查詢條件添加index,則會提高性能。 (只需要一次)

db.colecction.createIndex({"textId":1, "likes.likeId":1, "likes.creatorName":1})