mongodb使用updateOne和updateMany是可以的,只是方式不对
这几天在学习mongodb,在使用mongodb-client shell命令后,想使用java也试试
发现使用mongoCollection.updateOne 会报错,而使用
mongoCollection.replaceOne却不会报错,
我在网上搜索了下,网上找到的答案是
”分析:
应该是官方的update策略有变化,3.0以前,使用updateOne,3.0以后使用replaceOne
解决办法:
将updateOne替换为replaceOne即可 ”
这让我很费解,,如果是不建议使用了,为什么不直接废弃呢,不使用@deprecated这样的注解呢
我想,存在即合理,可用的,,
所以我使用断点找了很久很久
使用shell命令updateOne的方式是
db.collection.updateOne(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>
}
)
> db.testMongo.find({name:'zhaoliu'})
{ "_id" : ObjectId("591bf047b5ab733b38d06745"), "name" : "zhaoliu", "age" : "21" }
>
> db.testMongo.update({name:'zhaoliu'},{$set:{age:'1000'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.testMongo.find({name:'zhaoliu'})
{ "_id" : ObjectId("591bf047b5ab733b38d06745"), "name" : "zhaoliu", "age" : "1000" }
>
既然shell是这样的是的
为什么java代码不行呢
public void testMongogUpdateOne(){
MongoDatabase database = MongodbUtils.getDatabase("testMongo");
MongoCollection mongoCollection = database.getCollection("testMongo");
Document document = new Document("name", "zhaoliu");
Document documentNew = new Document("name", "aaa").append("age", 21);
mongoCollection.replaceOne(document, documentNew);
}
replaceOne是可以执行成功的
public void testMongogUpdateOne(){
MongoDatabase database = MongodbUtils.getDatabase("testMongo");
MongoCollection mongoCollection = database.getCollection("testMongo");
Document document = new Document("name", "zhaoliu");
Document documentNew = new Document("name", "aaa").append("age", 21);
mongoCollection.updateOne(document, documentNew);
}
而使用updateOne 却不行
Disconnected from the target VM, address: '127.0.0.1:52998', transport: 'socket'
java.lang.IllegalArgumentException: Invalid BSON field name age
at org.bson.AbstractBsonWriter.writeName(AbstractBsonWriter.java:516)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:188)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:131)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
at com.mongodb.connection.UpdateCommandMessage.writeTheWrites(UpdateCommandMessage.java:85)
at com.mongodb.connection.UpdateCommandMessage.writeTheWrites(UpdateCommandMessage.java:43)
at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBodyWithMetadata(BaseWriteCommandMessage.java:129)
at com.mongodb.connection.RequestMessage.encodeWithMetadata(RequestMessage.java:160)
at com.mongodb.connection.WriteCommandProtocol.sendMessage(WriteCommandProtocol.java:220)
at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:101)
at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.java:64)
at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.java:37)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:168)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:289)
at com.mongodb.connection.DefaultServerConnection.updateCommand(DefaultServerConnection.java:143)
at com.mongodb.operation.MixedBulkWriteOperation$Run$3.executeWriteCommandProtocol(MixedBulkWriteOperation.java:490)
at com.mongodb.operation.MixedBulkWriteOperation$Run$RunExecutor.execute(MixedBulkWriteOperation.java:656)
at com.mongodb.operation.MixedBulkWriteOperation$Run.execute(MixedBulkWriteOperation.java:409)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:177)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:168)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:422)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:413)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:168)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:74)
at com.mongodb.Mongo.execute(Mongo.java:845)
at com.mongodb.Mongo$2.execute(Mongo.java:828)
at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:550)
at com.mongodb.MongoCollectionImpl.update(MongoCollectionImpl.java:542)
at com.mongodb.MongoCollectionImpl.updateOne(MongoCollectionImpl.java:381)
at com.mongodb.MongoCollectionImpl.updateOne(MongoCollectionImpl.java:376)
at com.project.mongodb.MongodbUtils.testMongodbUpdateOneOther(MongodbUtils.java:136)
at com.project.mongodb.MongodbUtils.main(MongodbUtils.java:174)
我想是为啥client是用$set这样的修饰符的,,,而java中为啥是没有呢
我在debug时发现了这样的代码
public void writeName(String name) {
if(this.state != AbstractBsonWriter.State.NAME) {
this.throwInvalidState("WriteName", new AbstractBsonWriter.State[]{AbstractBsonWriter.State.NAME});
}
if(name == null) {
throw new IllegalArgumentException("BSON field name can not be null");
} else if(!((FieldNameValidator)this.fieldNameValidatorStack.peek()).validate(name)) {
throw new IllegalArgumentException(String.format("Invalid BSON field name %s", new Object[]{name}));
} else {
this.context.name = name;
this.state = AbstractBsonWriter.State.VALUE;
}
}
其中
if(!((FieldNameValidator)this.fieldNameValidatorStack.peek()).validate(name))
是调用
UpdateFieldNameValidator中的方式的
public boolean validate(String fieldName) {
return fieldName.startsWith("$");
}
发现是使用使用$开头所以
我将updateOne传入的参数改了下
public void testMongodbUpdateOneOther(){
MongoDatabase database = MongodbUtils.getDatabase("testMongo");
MongoCollection mongoCollection = database.getCollection("testMongo");
Document document = new Document("name", "zhaoliu");
Document modifiers = new Document();
Document documentNew = new Document();
documentNew.append("age", 210);
modifiers.append("$set", documentNew);
UpdateResult updateResult = mongoCollection.updateOne(document, modifiers);
System.out.println(updateResult.getMatchedCount());
}
这样就可以执行成功了
我将我在学习mongodb中遇到的问题分享出来,有不对之处请指出下,,谢谢