14

我的文档中有以下结构:

{
  _id : ObjectId("43jh4j343j4j"), 
  array : [
            { 
              _arrayId : ObjectId("dsd87dsa9d87s9d7"),
              someField : "something",
              someField2 : "something2"
            },
            { 
              _arrayId : ObjectId("sds9a0d9da0d9sa0"),
              someField : "somethingElse",
              someField2 : "somethingElse2"
            }
   ]
 }

我想更新someFieldsomeField2但仅针对数组中的一项,即与_arrayId匹配的一项(例如_arrayId : ObjectId("dsd87dsa9d87s9d7");并且仅针对此文档(例如_id : ObjectId("43jh4j343j4j"))而没有其他项。

arrayIds不是文档独有的,这就是我需要它用于特定文档的原因。如果我想为它存在的每个文档更新数组中的值,我可以使用$ positional operator它,但这不是我想要的。

我正在尝试在中完成此操作,但命令行解决方案也可以。

4

4 回答 4

24

这是 RameshVel 翻译成的解决方案:

    DB db = conn.getDB( "yourDB" ); 
    DBCollection coll = db.getCollection( "yourCollection" );

    ObjectId _id = new ObjectId("4e71b07ff391f2b283be2f95");
    ObjectId arrayId = new ObjectId("4e639a918dca838d4575979c");

    BasicDBObject query = new BasicDBObject();
    query.put("_id", _id);
    query.put("array._arrayId", arrayId);

    BasicDBObject data = new BasicDBObject();
    data.put("array.$.someField", "updated");

    BasicDBObject command = new BasicDBObject();
    command.put("$set", data);

    coll.update(query, command);
于 2011-09-15T14:35:15.020 回答
18

您仍然可以使用$ positional运算符来完成此操作。但是您需要指定父文档的 objectid 以及 _arrayid 过滤器。下面的命令行查询工作正常

db.so.update({_id:ObjectId("4e719eb07f1d878c5cf7333c"),
              "array._arrayId":ObjectId("dsd87dsa9d87s9d7")},
              {$set:{"array.$.someField":"updated"}})
于 2011-09-15T06:54:40.933 回答
1

...这是使用 mongo-driver version >= 3.1 的方法(我的是 3.2.2):

final MongoClient mongoClient = new MongoClient(new MongoClientURI(mongoURIString));
final MongoDatabase blogDatabase = mongoClient.getDatabase("yourDB");
MongoCollection<Document> postsCollection = blogDatabase.getCollection("yourCollection");

ObjectId _id = new ObjectId("4e71b07ff391f2b283be2f95");
ObjectId arrayId = new ObjectId("4e639a918dca838d4575979c");

Bson filter = Filters.and(Filters.eq( "_id", id ), Filters.eq("array._arrayId", arrayId));
Bson setUpdate = Updates.set("array.$.someField", "updated");
postsCollection.updateOne(postFilter, setUpdate);
于 2018-09-19T20:59:16.683 回答
1

看到没有一个答案实际上解释了如何在 Java 中执行此操作,以及 b) 对于嵌套数组项中的多个字段,这里是 mongo-java-driver 3.12.3 的解决方案。

import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import org.bson.Document;
import org.bson.types.ObjectId;

MongoClient mongoClient = MongoClients.create(...);
MongoDatabase db = mongoClient.getDatabase("testDb");
MongoCollection<Document> collection = db.getCollection("testCollection");
collection.updateOne(
    Filters.and(
            Filters.eq("_id", new ObjectId("43jh4j343j4j")),
            Filters.eq("array._arrayId", new ObjectId("dsd87dsa9d87s9d7"))
    ),
    Updates.combine(
            Updates.set("array.$.someField", "new value 1"),
            Updates.set("array.$.someField2", "new value 2")
    )
);

这个线程帮助我找到了正确的解决方案,但我必须为完整的解决方案做更多的研究,所以希望其他人也能从我的回答中受益。

于 2020-09-02T18:55:22.317 回答