Java 使用Mongo游标更新文档的正确方法是什么?
我正在尝试使用游标更新Mongo DB中的文档。我的Mongo DB Java驱动程序版本是3.3.0。下面是我的代码片段Java 使用Mongo游标更新文档的正确方法是什么?,java,mongodb,mongodb-java,mongodb-java-3.3.0,Java,Mongodb,Mongodb Java,Mongodb Java 3.3.0,我正在尝试使用游标更新Mongo DB中的文档。我的Mongo DB Java驱动程序版本是3.3.0。下面是我的代码片段 MongoCollection<Document> collection = mongoDb.getCollection("customer"); MongoCursor<Document> cursor = collection.find().iterator(); try{ while(cursor.hasNext()){
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();
}
MongoCollection collection=mongoDb.getCollection(“客户”);
MongoCursor=collection.find().iterator();
试一试{
while(cursor.hasNext()){
Document oldDoc=cursor.next();
//创建了新文档newDoc
collection.replaceOne(旧文档、新文档);
}
}捕获(例外e){
e、 printStackTrace();
}
通过这种方式,我可以更新文档,我认为这不是一种有效的方式,因为这里的集合被搜索了2次。我想用一些值更新旧文档,然后用一些方法保存它,如collection.update(oldDoc)或collection.save(oldDoc),而不创建新文档。我搜索了一下,发现了下面的帖子
这正是我想要的,但在新API中找不到save()方法。我这里有三个问题
不要担心额外的搜索,
replaceOne
方法的第一个参数是过滤器。使用旧文档作为过滤器将使用文档的_id属性,该属性应该相对较快。
因此,基本上,你这样做的方式是正确的。但请记住,该操作是非事务性的,这意味着更新可能会影响游标的结果集。因此,更新后的文档可能会存储在光标尚未经过的位置,从而导致文档被处理两次
关于你的问题
save
方法的语义是更新或插入文档(如果还不存在的话)(又称upsert)。最接近MongoCollection
的是upsert
设置为true。这就是save
命令的基本功能。但是如果替换文档是原始文档的修改版本,则replaceOne
会导致相同的结果\u id
,修改oldDoc并使用它而不是新文档UpdateOptions upsert = new UpdateOptions().upsert(true);
Bson idFilter = Filters.eq("_id", oldDoc.getObjectId("_id"));
//modify the oldDoc
oldDoc. ...
collection.replaceOne(idFilter, oldDoc, upsert);
你能看一下吗?
findOneAndUpdate()
?当只有一个文档与筛选器匹配时,两者的行为方式相同。但当多个文档匹配时,行为会有所不同。它还返回未修改的文档,但如果更新的文档依赖于该数据,FindUpdate将不会帮助您。从技术上讲,findAndUpdate
或findAndModify
是一个命令,而save()
是一个insert()
如果更新的文档有\u id
或者update()
如果没有\u id
则是一个带有upsert=true的更新()
。我仍然不明白replaceOne
如何更接近save()
。您不能使用replaceOne
修改(更新)。您可以使用update*
,它更接近我前面提到的save
或find*update*
。这些方法中有许多具有相似和重叠的行为以及细微的差异,取决于要替换的文档,结果行为可能与update相同。为了理解这种行为,有时查看实现会有所帮助,即在shelldb中。yourCollection.save
(不带括号)显示javascript实现save
通过insert
和update
实现,findAndModify
是一个命令,replaceOne
是一个批量操作。但是java驱动程序中没有save
,最接近的函数是update,upsert=true。