我知道之前已经问过这个问题,但我还没有找到一个有效的解决方案。我正在使用MongoDB C#驱动程序,尽管这是关于MongoDB操作的一般问题。
我的文档结构如下所示:
field1: value1
field2: value2
...
users: [ {...user 1 subdocument...}, {...user 2 subdocument...}, ... ]
一些事实:
我想弄清楚如何有效地做到这一点。从我所听到的,你不能一次性将几个数组元素直接设置为新值,所以我不得不尝试别的东西。
我尝试使用$ pullAll / $ AddToSet + $每个操作删除旧数组并将其替换为修改后的数组。我知道$ pullall只能删除我需要的元素,但我想保留元素的顺序。
C#代码:
try
{
WriteConcernResult wcr = collection.Update(query,
Update.Combine(Update.PullAll("users"),
Update.AddToSetEach("users", newUsers.ToArray())));
}
catch (WriteConcernException wce)
{
return wce.Message;
}
在这种情况下,newUsers是List<BsonValue>
转换为数组。但是我收到以下异常消息:
无法同时更新“用户”和“用户”
从外观上看,我在同一个写操作中不能在同一个字段上使用两个更新语句。
我也试过Update.Set("users", newUsers.ToArray())
,但显然Set语句不适用于数组,只是基本值:
参数2:无法从'MongoDB.Bson.BsonValue []'转换为'MongoDB.Bson.BsonValue'
然后我尝试将该数组转换为BsonDocument:
Update.Set("users", newUsers.ToArray().ToBsonDocument());
得到了这个:
无法将Array值写入BSON文档的根级别。
我可以尝试更换整个文档,但这似乎有点矫枉过正,而且效率肯定不高。
所以我现在唯一能想到的就是运行两个单独的写操作:一个用于删除不需要的旧用户,另一个用新版本替换它们:
WriteConcernResult wcr = collection.Update(query, Update.PullAll("users"));
WriteConcernResult wcr = collection.Update(query, Update.AddToSetEach("users", newUsers.ToArray()));
这是我最好的选择吗?或者还有另一种更好的方法吗?
答案 0 :(得分:2)
您的代码应该稍作改动:
Update.Set("users", new BsonArray(newUsers));
BsonArray是一个BsonValue,其中一个文档数组不是,我们不会像我们做其他原始值一样隐式转换数组。
答案 1 :(得分:0)
这个扩展方法解决了我的问题:
public static class MongoExtension
{
public static BsonArray ToBsonArray(this IEnumerable list)
{
var array = new BsonArray();
foreach (var item in list)
array.Add((BsonValue) item);
return array;
}
}