简体   繁体   English

Arangodb从文档中删除子项目

[英]Arangodb removing subitems from document

How does one remove subitems from a document. 如何从文档中删除子项目。 So say I have a document called sales with each sale has a sale.item which contains {name,price,code}. 假设我有一个名为sales的文档,每笔交易都有一个sales.item,其中包含{name,price,code}。

I want to remove each item which is not valid, by checking the code for blank or null. 我想通过检查代码是否为空或null来删除无效的每个项目。

Trying something like below fails with errors, am not sure if I need to use sub-query and how. 尝试以下类似操作失败并显示错误,不确定我是否需要使用子查询以及如何使用。

FOR sale in sales
FOR item in sale.items
    FILTER item.code == ""
REMOVE item IN sale.items

Another attempt 另一尝试

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

The following query will rebuild the items for each document in sales . 以下查询将为sales每个文档重建项目。 It will only keep item whose code is not null and not the empty string: 它将仅保留其代码不为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

Here is the test data I used: 这是我使用的测试数据:

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" }
  ]
});

There's a better way to do this, without sub-queries. 没有子查询,这是一种更好的方法。 Instead, a function for removing an array element, will be used: 相反,将使用删除数组元素的函数:

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 takes an array as the first argument, and an array item inside that array as the second argument, and returns an array that has all the items of the first argument, but without that specific item that was in the second argument. REMOVE_VALUE将一个数组作为第一个参数,并将该数组内的一个数组项作为第二个参数,并返回一个数组,该数组具有第一个参数的所有项,但第二个参数中没有该特定项。

Example: 例:

REMOVE_VALUE([1, 2, 3], 3) = [1, 2]

Example with subdocuments being the values: 子文档为值的示例:

REMOVE_VALUE( [ {name: cake}, {name: pie, taste: delicious}, {name: cheese} ] , {name: cheese}) = [ {name: cake}, {name: pie, taste: delicious} ]

You cannot just use REMOVE_VALUE separately, the way you use the REMOVE command separately. 您不能仅单独使用REMOVE_VALUE,就不能单独使用REMOVE命令。 You must use it as part of an UPDATE command not as part of a REMOVE command. 您必须将它用作UPDATE命令的一部分,而不是REMOVE命令的一部分。 Unfortunately, the way it works is to make a copy of the "items" list inside your one specific "doc" that you are currently dealing with, but the copy has the subdocument you don't like, removed from the "items" list. 不幸的是,它的工作方式是在您当前正在处理的一个特定“文档”中复制“项目”列表,但是该副本包含您不喜欢的子文档,已从“项目”列表中删除。 That new copy of the list replaces the old copy of the items list. 列表的新副本替换了项目列表的旧副本。

There is one more, most efficient way to remove subdocuments from a list - and that is by accessing the specific cell of the list with items[2] - and you have to use fancy array functions even fancier than the one I used here, to find out the specific cell in the list (whether it's [2] or [3] or [567]) and then to replace the contents of that cell with Null, using the UPDATE command, and then to set the options to KeepNull = false. 还有另一种最有效的从列表中删除子文档的方法-即通过使用items [2]访问列表的特定单元格-而且您必须使用比我在此使用的奇特的花式数组函数。在列表中查找特定的单元格(是[2]还是[3]或[567]),然后使用UPDATE命令用Null替换该单元格的内容,然后将选项设置为KeepNull = false 。 That's the "most efficient" way to do it but it would be a monstrous looking complicated query ): I might write that query later and put it here but right now .. I would honestly suggest using the method I described above, unless you have a thousand subdocuments in each list. 那是“最有效”的方法,但是看起来很复杂。):我可能稍后再写该查询,然后放在这里,但是现在..老实说,我建议使用上面描述的方法,除非您有每个列表中有一千个子文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM