如何从文档中删除子项目。所以说我有一个名为sales的文件,每个销售都有一个sale.item,其中包含{name,price,code}。
我想删除每个无效的项目,方法是检查代码为空或空。
尝试类似下面的内容会因错误而失败,我不确定是否需要使用子查询以及如何使用。
FOR sale in sales
FOR item in sale.items
FILTER item.code == ""
REMOVE item IN sale.items
另一次尝试
FOR sale in sales
LET invalid = (
FOR item in sale.items
FILTER item.code == ""
RETURN item
)
REMOVE invalid IN sale.items LET removed = OLD RETURN removed
答案 0 :(得分:3)
以下查询将重建sales
中每个文档的项目。它只会保留代码不是null
的项目,而不是空字符串:
FOR doc IN sales
LET newItems = (
FOR item IN doc.items
FILTER item.code != null && item.code != ''
RETURN item
)
UPDATE doc WITH { items: newItems } IN sales
以下是我使用的测试数据:
db.sales.insert({
items: [
{ code: null, what: "delete-me" },
{ code: "", what: "delete-me-too" },
{ code: "123", what: "better-keep-me" },
{ code: true, what: "keep-me-too" }
]
});
db.sales.insert({
items: [
{ code: "", what: "i-will-vanish" },
{ code: null, what: "i-will-go-away" },
{ code: "abc", what: "not me!" }
]
});
db.sales.insert({
items: [
{ code: "444", what: "i-will-remain" },
{ code: null, what: "i-will-not" }
]
});
答案 1 :(得分:1)
没有子查询,有更好的方法可以做到这一点。相反,将使用删除数组元素的函数:
FOR doc IN sales
FOR item IN doc.items
FILTER item.code == ""
UPDATE doc WITH { items: REMOVE_VALUE( doc.items, item ) } IN sales
REMOVE_VALUE将数组作为第一个参数,并将该数组中的数组项作为第二个参数,并返回一个数组,其中包含第一个参数的所有项,但没有第二个参数中的特定项。
示例:
REMOVE_VALUE([1, 2, 3], 3) = [1, 2]
子文档为值的示例:
REMOVE_VALUE( [ {name: cake}, {name: pie, taste: delicious}, {name: cheese} ] , {name: cheese}) = [ {name: cake}, {name: pie, taste: delicious} ]
您不能单独使用REMOVE_VALUE,就像单独使用REMOVE命令一样。必须将其用作UPDATE命令的一部分,而不是REMOVE命令的一部分。不幸的是,它的工作方式是复制"项目"列出你的一个特定的" doc"你目前正在处理的,但副本上有你不喜欢的子文档,从"项目"名单。该列表的新副本将替换项目列表的旧副本。
还有一种更有效的方法从列表中删除子文档 - 这是通过使用项[2]访问列表的特定单元格 - 你必须使用比我使用的更奇特的花哨的数组函数在这里,找出列表中的特定单元格(无论是[2]还是[3]或[567])然后用Null替换该单元格的内容,使用UPDATE命令,然后到将选项设置为KeepNull = false。这是最有效的"这样做的方法,但这将是一个看起来很可怕的复杂查询):我可能稍后写这个查询并把它放在这里但是现在..我会诚实地建议使用我上面描述的方法,除非你在每个列表中有一千个子文档