作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何更新数组元素子文档中的特定字段?
我的问题与下面的类似,但就我而言,我只需要更新一个子文档值。
MongoDB: How do I update a single subelement in an array, referenced by the index within the array?
我有以下文档模型:
{
_id : "xpto",
other_stuff ... ,
templates : [
{
templateId:"template-a"
body: {
en_US:"<p>Hello World!</p>"
}
},
{
templateId:"template-b"
body: {
es_ES:"<p>Holla !</p>"
}
}
]
}
因此,在 mongodb shell 中,以下语句非常适合我:
db.apiClient.update({"_id":"xpto","templates.templateId":"template-b"}, {$set:{"templates.$.body.es_ES":"<h1>Gracias !</h1>"}})
但是,当我尝试使用 Mongo Java 驱动程序执行此操作时,我收到 IllegalArgumentException。
BasicDBObject selectQuery = new BasicDBObject("_id", "xpto");
selectQuery.put("templates.templateId", "template-b");
BasicDBObject updateQuery = new BasicDBObject();
for(String locale : template.getBody().keySet()) {
String updateBodyLocaleExpression = new StringBuilder()
.append("templates.$.body.").append(locale).toString();
String updateBodyLocaleValue = template.getBody().get(locale);
updateQuery.put(updateBodyLocaleExpression, updateBodyLocaleValue);
}
updateQuery.put("$set", updateQuery);
getCollection(COLLECTION_NAME).update(selectQuery, updateQuery, true, true);
它抛出以下异常:
Caused by: java.lang.IllegalArgumentException: Invalid BSON field name templates.$.body.es_ES
at org.bson.AbstractBsonWriter.writeName(AbstractBsonWriter.java:494)
at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:127)
at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:61)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
at com.mongodb.connection.RequestMessage.addDocument(RequestMessage.java:253)
at com.mongodb.connection.RequestMessage.addCollectibleDocument(RequestMessage.java:219)
at com.mongodb.connection.UpdateMessage.encodeMessageBodyWithMetadata(UpdateMessage.java:77)
at com.mongodb.connection.RequestMessage.encodeWithMetadata(RequestMessage.java:160)
at com.mongodb.connection.WriteProtocol.execute(WriteProtocol.java:85)
我的代码有问题吗?
谢谢。
最佳答案
是的。您构造了错误的 updateQuery
。您将字段 templates.$.body...
放入 BasicDbObject 中,然后将相同的文档添加到 $set
字段中。 MongoDB 尝试更新 field templates.$.body.
,这里 $
是字段名称的一部分,而不是运算符。
这是工作示例:
//List is for testing purposes only
List<String> locales = Arrays.asList("en_US", "en_UK");
Document query = new Document("_id", "xpto")
.append("templates.templateId", "template-b");
Document updateQuery = new Document();
for (String locale : locales) {
updateQuery.put("templates.$.body." + locale, "<pre>Updated " + locale + "</pre>");
}
collection.updateOne(query, new Document("$set", updateQuery));
Document 与 BasicDbObject 几乎相同,但更通用。
关于java - Mongo Java 驱动程序 - 如何将子文档更新为数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37883122/
我是一名优秀的程序员,十分优秀!