当前位置: 首页 > 知识库问答 >
问题:

Mongo Java 驱动程序 - 如何将子文档更新为数组元素

薛利
2023-03-14

如何更新数组元素子文档中的特定字段?

我的问题类似于下面的问题,但是在我的例子中,我只需要更新一个子文档值。

MongoDB:如何更新数组中由数组中的索引引用的单个子元素?

我有以下文档模型:

{
  _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>"}})

然而,当我尝试使用MongoJava驱动程序时,我会得到一个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)

我的代码有问题吗?

谢谢你。

共有1个答案

裴华荣
2023-03-14

是的。您构造了错误的更新查询。您将字段 templates.$.body... 放入 BasicDbObject 中,然后将相同的文档添加$set字段中。MongoDB尝试更新字段模板.$.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));

文档与BasicDbObject几乎相同,但更为通用。

 类似资料:
  • 问题内容: 我正在使用MongoDB数据库,该数据库的收集模型包括 班级 , 学生 , 学科 和[学术] 表现 。以下是基于猫鼬的架构和模型: 该集合的文件是最复杂的地段; 示例文档为: 我能够使用以下代码检索现有的班级文档并将其添加到分数中: 但是,如何添加/更新/删除该特定学生的成绩?我需要能够通过以下方式与集合进行交互: 检索所有学生或特定学生的分数(检索数组中的特定元素) 为特定主题添加/

  • 将mongodb与pymongo一起使用,我有以下文档: 我想更新示例子文档(这是一个数组元素,因为可能有多个示例)。我有以下代码,但它不工作... 谁能告诉我这个有什么问题吗?

  • 问题内容: 您好,我想将chrome驱动程序更新到最新版本,但ant会找到有关更新驱动程序的任何信息,只是有关安装它的信息。我需要怎么做才能将驱动程序更新到最新版本? 问题答案: chromedriver是一个独立的可执行文件。只需将您的现有版本替换为较新的版本即可。 从https://sites.google.com/a/chromium.org/chromedriver/downloads下载

  • [debug]应用程序-update(){“_id”:{“$OID”:“5759542A4E0BF602ADCAB149”},“title”:“文本平铺”,“信誉”:0} [debug]application-org.mongodb.scala.observableImplicits$boxedobservable@61ddc581 [debug]application-onsubscribe:o

  • 我正在尝试使用MongoJava驱动程序3.6的新更改流功能,但我卡住了。这是我的错误: 下面是我启动changeStream的方法: < code>Person只是一个POJO。

  • < li >感谢您点击这个问题!我已经尽了最大努力让这件事尽可能彻底。 < li >但是,如果您需要进一步澄清,请随时告诉我! < li >如果您认为问题太长。你可以读第三个 Mongodb Java 驱动程序: org.mongodb:mongo-java-driver:3.11.0-rc0 查找具有特定“名称”字段的特定文档 然后更新其他字段或整个文档 从不返回null。 Java只告诉我它返