我正在尝试使用游标更新Mongo DB中的文档。我的Mongo DB Java驱动程序版本是3.3.0。以下是我的代码段。
MongoCollection<Document> collection = mongoDb.getCollection("customer");
MongoCursor<Document> cursor = collection.find().iterator();
try{
while(cursor.hasNext()){
Document oldDoc = cursor.next();
//created new Document newDoc
collection.replaceOne(oldDoc, newDoc);
}
}catch(Exception e){
e.printStackTrace();
}
虽然这样,我可以更新文档,我认为这不是有效的方式,因为此处正在搜索集合2次。我想用一些值更新旧文档,稍后再进行想要使用某些方法保存它,例如 collection.update(oldDoc)或 collection.save(oldDoc)而不创建新文档。我搜索并发现了以下帖子。
Java, MongoDB: How to update every object while iterating a huge collection?
这正是我想要的,但我在新API中找不到 save() 方法。所以我在这里有3个问题。
答案 0 :(得分:0)
不要担心额外搜索,created_at
方法的第一个参数是过滤器。使用旧文档作为过滤器将使用文档的_id属性,该属性应该相对较快。
基本上,你这样做的方式是正确的。但请记住,该操作是非事务性的,这意味着更新可能会影响游标的结果集。因此,可能会发生更新的文档将存储在光标尚未通过的位置,从而导致文档被处理两次。
关于你的问题。
mongo shell中replaceOne
方法的语义是更新或插入文档(如果尚未存在(也称为upsert))。与save
最接近的是[{3}},其中updateOne()
MongoCollection
设置为true。这基本上是upsert
命令的作用。但如果替换文档是原始文档的修改版本,则save
会导致相同的结果。
为什么担心对象创建?在java中它接下来是免费的,不用担心GC或内存消耗,因为那些短暂的对象是GC非常快。如果您希望代码更简洁,可以使用oldDoc的replaceOne
创建专用过滤器对象,修改oldDoc并使用它而不是新文档。
例如:
_id