使用官方C#驱动程序更新MongoDB中的嵌入式文档
如果我有一个包含嵌入式部门的公司集合:
{ "_id": 1 "_t": "Company", "Name": "Test Company" "Divisions": [ { "_id": 1 "_t": "Division", "Name": "Test Division 1" }, { "_id": 2 "_t": "Division", "Name": "Test Division 2" } ] }
使用官方10gen C#驱动程序时保存/更新整个部门的最佳方法是什么? (最新的0.9版本。)
我正在使用Update.AddToSetWrapped来添加Divisions,这很好用,但我也希望能够根据它们的_id更新文档。
例如,如果我定义以下Update方法:
public void UpdateDivision(IDivision division) { var mongo = MongoServer.Create(_connectionString); var database = mongo.GetDatabase(_databaseName); var query = Query.EQ("_id", division.CompanyId); var update = Update.AddToSetWrapped("Divisions", division); database.GetCollection("Company") .Update(query, update, UpdateFlags.Upsert, SafeMode.True); }
并称之为:
var division = GetDivisionById(1); division.Name = "New Name"; UpdateDivision(division);
然后将一个新的Division实例添加到集合中,因为虽然“_id”仍然是1,但Name是不同的,因此它是一个唯一的文档。
那么有什么更新整个嵌入式文档的好方法呢?
在我想出一个更好的解决方案之前,我将首先$pull
原来的分区$pull
,然后用修改后的分区将$addToSet
$pull
$addToSet
。 这有效,但显然不理想,因为它执行两个单独的更新。
您可以使用MongoDB的位置数组修改function一次更新数组中的整个分区,如下所示:
var division = GetDivisionById(1); division.Name = "New Name"; // change any other properties of division you want collection.Update( Query.EQ("Divisions._id", 1), Update.Set("Divisions.$", BsonDocumentWrapper.Create(division)) );
这里发生的关键事情是:
- 在Update.Set中使用“$”
- 由于Update.Set需要BsonValue作为其第二个参数,我们必须使用BsonDocumentWrapper来保存除法值(要创建的IDivision类型参数将序列化时的nominalType设置为IDivision,这导致写入“_t”鉴别器)。