簡體   English   中英

如何使用java驅動程序更新mongo db中的文檔字段?

[英]How do I update fields of documents in mongo db using the java driver?

參考文獻:

仍然是mongo db的新手,但我正在嘗試更新集合中現有文檔的一部分......遺憾的是,上面的鏈接沒有更新示例。

基本上,我只是希望能夠:

  1. 向文檔添加新字段
  2. 將文檔的現有字段更新為新值

這是我的代碼(Grails + Groovy + Java + MongoDB + java驅動程序):

def shape = mongo.shapes.findOne(new BasicDBObject("data", "http://www.foo.com")); // get the document
mongo.shapes.update(new BasicDBObject("_id", shape._id), new BasicDBObject("isProcessed", 0));  // add a new "isProcessed" field set to 0
mongo.shapes.update(new BasicDBObject("_id", shape._id), new BasicDBObject("data", "http://www.bar.com"));

這幾乎破壞了整個對象...我可能只是嘗試修改原始形狀對象,然后在其上運行更新。 但在那之前, 是否有人有更新單個字段(而不是整個文檔)的經驗?

編輯:

我只是嘗試了它,並且能夠通過發送整個對象以及新的和/或更新的字段來成功更新。 我想知道驅動程序是否足夠聰明,只更新最小的更改子集,或者只是盲目更新整個事物? (在下面的例子中,它只是更新電線或整個形狀文檔的foo字段?)

碼:

def shape = mongo.shapes.findOne(); // get the first shape to use as a base
shape.removeField("_id");  // remove the id field
shape.put("foo","bar");  // add a new field "foo"
mongo.shapes.insert(shape);  // insert the new shape
def shape2 = mongo.shapes.findOne(new BasicDBObject("foo", "bar"));  // get the newly inserted shape (and more importantly, it's id)
shape2.put("foo", "bat");  // update the "foo" field to a new value
mongo.shapes.update(new BasicDBObject("_id", shape2._id), shape2);  // update the existing document in mongo

我想知道驅動程序是否足夠聰明,只更新最小的更改子集,或者只是盲目更新整個事物?

不,如果您使用“正常”更新方法,整個對象將通過網絡發送。 我懷疑數據庫服務器本身將足夠聰明,只能更新必要的索引(而不是那些沒有改變的索引),如果可能的話(即對象可以在適當的位置更新而不必移動,因為它也增長了許多)

你可以做的是使用“原子更新修飾符”功能。 Java文檔對它們有點了解,但由於驅動程序只傳輸JSON,因此非Java教程中的內容應該可以工作,例如:

shapes.update((DBObject)JSON.parse(    "{ 'foo' : 'bar'}"),  
    (DBObject) JSON.parse(          "{ '$set' : { 'foo': 'bat'}}")   );

在這里找到一個示例 ,它似乎顯示了更新調用的用法。 所以對於你的例子,我相信這樣的事情應該有用嗎?

// Find an object
def shape2 = mongo.shapes.findOne( new BasicDBObject( 'foo', 'bar' ) )
// And update the foo field from 'bar' to 'bat'
mongo.shapes.update( shape2, new BasicDBObject( '$set', new BasicDBObject( 'foo', 'bat' ) ) )

編輯

您可以使用類別以更加時髦的方式構建BasicDBObjects ...

這樣的事情可能會這樣:

class BasicDBObjectMapBuilder {
  static String toDbObj( String s ) { s }
  static BasicDBObject toDbObj( Map m ) {
    m.inject( null ) { r, it -> new BasicDBObject( it.key, it.value.toDbObj() ) }
  }
}

use( BasicDBObjectMapBuilder ) {
  def shape2 = mongo.shapes.findOne( new BasicDBObject( 'foo', 'bar' ) )
  // And update the foo field from 'bar' to 'bat'
  mongo.shapes.update( shape2, [ '$set':[ 'foo', 'bat' ] ].toDbObj() )
}

我沒有測試過這個......

編輯2

實際上,BasicDBObject是一個Map,所以你應該能夠做到:

  mongo.shapes.update( shape2, [ '$set':[ 'foo', 'bat' ] ] as BasicDBObject )

不需要建設者

這篇文章的很多答案都是使用舊版本的Mongo Java Driver。 如果您使用的是較新版本的Java驅動程序(v3.0 +),則首選方法似乎是使用Document對象而不是DBObject接口。

這是一個例子:

MongoClient client = new MongoClient();
MongoCollection<Document> fooCollection = client.getDatabase("test").getCollection("foo");

Bson filter = Filters.eq("_id", "123d45678c467bb433c99f99");
Bson updates = Updates.set("isFoo", true);
fooCollection.findOneAndUpdate(filter, updates);

這個答案使用了mongo shell,但展示了如何深入到JSON對象結構來修改特定字段而不覆蓋其余字段。

給定名為“my_collection”的集合中的JSON對象:

{ 
  "_id" : ObjectId("50fdb2a73f7bc7a5acecc4f8"), 
  "data" : { 
    "list" : [ 0, 1, 2, 7, 4, 5 ], 
    "subobj" : { 
       "var_a":"valuea",
       "var_b":"valueb" 
     }
  }
}

要更新'var_b',而不覆蓋其他任何內容:

db.my_collection.update({"_id":"50fdb2a73f7bc7a5acecc4f8"}, { "$set":{"data.subobj.var_b":"new_value"}})

要使用值“99”更新數組“list”中的第3個元素,而不覆蓋其他任何內容:

db.my_collection.update({"_id":"50fdb2a73f7bc7a5acecc4f8"}, { "$set":{"data.list.2":"99"} } )
DBCollection dbCollection = db.getCollection("mycollection");
BasicDBObject dbObject = new BasicDBObject();
dbObject.put("_id", "3"); 
// your update condition - or the query
DBObject newObject =  dbCollection.find(dbObject).toArray().get(0);
// I just take the first element. Can iterate through as per your requirement if multiple fields        exist
newObject.put("key","value");
//add field, either a new field or any existing field
dbCollection.findAndModify(dbObject, newObject);

只需使用上述步驟即可。 您可以更改詳細信息,而不會影響與同一密鑰關聯的其他項目。

//更新

WriteResult usr = (WriteResult)mongoOperation.upsert(new  Query(Criteria.where("name").is("till")),  

Update.update("password", "jk45"), "collection");

System.out.println("updatedUser : " + usr );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM