Arangodb 从文档中删除子项
Arangodb removing subitems from document
如何从文档中删除子项。假设我有一个名为 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
以下查询将为 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" }
]
});
有一种更好的方法可以做到这一点,无需子查询。相反,将使用删除数组元素的函数:
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 将一个数组作为第一个参数,该数组中的一个数组项作为第二个参数,returns 一个包含第一个参数的所有项的数组,但没有第二个参数中的特定项目。
示例:
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 命令那样单独使用 REMOVE_VALUE。您必须将它用作 UPDATE 命令的一部分而不是 REMOVE 命令的一部分。不幸的是,它的工作方式是在您当前正在处理的特定 "doc" 中复制 "items" 列表,但该副本包含您不喜欢的子文档,已从"items" 列表。该列表的新副本将替换项目列表的旧副本。
还有一种最有效的方法可以从列表中删除子文档——那就是通过使用 items[2] 访问列表的特定单元格——而且你必须使用比那个更高级的数组函数我在这里使用,找出列表中的特定单元格(无论是 [2] 或 [3] 还是 [567]),然后使用 UPDATE 命令将该单元格的内容替换为 Null,然后设置KeepNull = false 的选项。这是 "most efficient" 的方法,但它会是一个看起来很复杂的查询:我可能会稍后编写该查询并将其放在这里但现在..我会诚实地建议使用我上面描述的方法,除非你每个列表中有一千个子文档。
如何从文档中删除子项。假设我有一个名为 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
以下查询将为 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" }
]
});
有一种更好的方法可以做到这一点,无需子查询。相反,将使用删除数组元素的函数:
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 将一个数组作为第一个参数,该数组中的一个数组项作为第二个参数,returns 一个包含第一个参数的所有项的数组,但没有第二个参数中的特定项目。
示例:
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 命令那样单独使用 REMOVE_VALUE。您必须将它用作 UPDATE 命令的一部分而不是 REMOVE 命令的一部分。不幸的是,它的工作方式是在您当前正在处理的特定 "doc" 中复制 "items" 列表,但该副本包含您不喜欢的子文档,已从"items" 列表。该列表的新副本将替换项目列表的旧副本。
还有一种最有效的方法可以从列表中删除子文档——那就是通过使用 items[2] 访问列表的特定单元格——而且你必须使用比那个更高级的数组函数我在这里使用,找出列表中的特定单元格(无论是 [2] 或 [3] 还是 [567]),然后使用 UPDATE 命令将该单元格的内容替换为 Null,然后设置KeepNull = false 的选项。这是 "most efficient" 的方法,但它会是一个看起来很复杂的查询:我可能会稍后编写该查询并将其放在这里但现在..我会诚实地建议使用我上面描述的方法,除非你每个列表中有一千个子文档。