2016-06-17 10 views
0

配列要素のサブ文書の特定のフィールドを更新するにはどうすればよいですか?Mongo Java Driver - サブ文書を配列要素に更新する方法

私の質問は以下のようなものですが、私の場合はサブ文書の値を更新する必要があります。

MongoDB: How do I update a single subelement in an array, referenced by the index within the array?

I次documentoモデルがあります:

{ 
    _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のでは次の文をシェルが私のために完璧に動作します:

db.apiClient.update({"_id":"xpto","templates.templateId":"template-b"}, {$set:{"templates.$.body.es_ES":"<h1>Gracias !</h1>"}}) 

をしかし、私はしようとすると、それはMongo Java Driverで、私は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

はい。あなたは間違ってupdateQueryを構成します。フィールドtemplates.$.body...をBasicDbObjectに入れ、同じ文書を$setフィールドに追加します。 MongoDBはフィールド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)); 

文書は、ほぼBasicDbObjectと同じですが、より一般的です。

+0

Thanks Vadeg! :) –

関連する問題