【发布时间】:2018-02-19 14:26:03
【问题描述】:
我有以下表示项目的 JSON 结构
{
Id: "a",
Array1: [{
Id: "b",
Array2: [{
Id: "c",
Array3: [
{...}
]
}]
}]
}
我需要能够将 Array2 中的数组元素替换为新项目,或者仅将 Array3 替换为新数组。
这是我替换Array2中的数组项的代码:
await Collection.UpdateOneAsync(
item => item.Id.Equals("a") &&
item.Array1.Any(a => a.Id.Equals("b")) &&
item.Array1[-1].Array2.Any(b => b.Id.Equals("c")),
Builders<Item>.Update.Set(s => s.Array1[-1].Array2[-1], newArray2Item)
);
执行此代码时出现此错误:
"A write operation resulted in an error.
Too many positional (i.e. '$') elements found in path 'Array1.$.Array2.$'"
这是我在Array2 中替换Array3 的代码:
await Collection.UpdateOneAsync(
item => item.Id.Equals("a") &&
item.Array1.Any(a => a.Id.Equals("b")) &&
item.Array1[-1].Array2.Any(b => b.Id.Equals("c")),
Builders<Item>.Update.Set(s => s.Array1[-1].Array2[-1].Array3, newArray3)
);
这是错误:
"A write operation resulted in an error.
Too many positional (i.e. '$') elements found in path 'Array1.$.Array2.$.Array3'"
我正在使用 C# MongoDB 驱动程序版本 2.5.0 和 MongoDB 版本 3.6.1
我发现这张 Jira 票 Positional Operator Matching Nested Arrays 说问题已得到解决,他们建议使用此语法进行更新
Update all matching documents in nested array:
db.coll.update({}, {$set: {“a.$[i].c.$[j].d”: 2}}, {arrayFilters: [{“i.b”: 0}, {“j.d”: 0}]})
Input: {a: [{b: 0, c: [{d: 0}, {d: 1}]}, {b: 1, c: [{d: 0}, {d: 1}]}]}
Output: {a: [{b: 0, c: [{d: 2}, {d: 1}]}, {b: 1, c: [{d: 0}, {d: 1}]}]}
所以我将它转换为我的元素:
db.getCollection('Items').update(
{"Id": "a"},
{$set: {"Array1.$[i].Array2.$[j].Array3": [newArray3]}},
{arrayFilters:
[
{"i.Id": "b"},
{"j.Id": "c"}
]}
)
得到了这个错误:
cannot use the part (Array1 of Array.$[i].Array2.$[j].Array3) to traverse the element
关于如何解决此错误的任何想法?
【问题讨论】:
-
它并不漂亮,但作为一种快捷方式,您始终可以使用字符串编写更新,就像在 shell 中编写它们一样,然后将它们传递给
Update()方法。 -
这就是我从 Jira 提供样本的原因。还是不行,,,
-
你需要一个更新的客户端才能工作(试试你的发行版附带的“mongo.exe”shell):stackoverflow.com/questions/47225822/…
-
我不能在 C# 中使用
mongo.exe...你发给我的链接是在谈论 robomongo。 -
我知道。 ;) 您在示例中给出的最后一个查询是一个基于字符串的查询,您应该能够在 mongo.exe 中运行而不会出现错误。这就是我要说的。一旦你的查询工作正常,你就可以使用过滤器并更新它的一部分来创建一个 C# 版本。
标签: mongodb mongodb-.net-driver