1

如何从文档中删除子项。假设我有一个名为 sales 的文档,每次销售都有一个包含 {name,price,code} 的 sale.item。

我想通过检查代码是否为空白或空来删除每个无效的项目。

尝试类似下面的操作失败并出现错误,不确定我是否需要使用子查询以及如何使用。

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
4

2 回答 2

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" }
  ]
});
于 2015-04-01T17:46:09.177 回答
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 命令那样单独使用 REMOVE_VALUE。您必须将其用作 UPDATE 命令的一部分,而不是 REMOVE 命令的一部分。不幸的是,它的工作方式是在您当前正在处理的一个特定“文档”中制作“项目”列表的副本,但该副本包含您不喜欢的子文档,已从“项目”列表中删除. 该列表的新副本替换了项目列表的旧副本。

还有一种最有效的方法可以从列表中删除子文档——那就是通过使用 items[2] 访问列表的特定单元格——你必须使用比我在这里使用的更漂亮的数组函数来找出列表中的特定单元格(无论是 [2] 还是 [3] 还是 [567]),然后使用 UPDATE 命令将该单元格的内容替换为 Null,然后将选项设置为 KeepNull = false . 这是“最有效”的方法,但它会是一个看起来很复杂的查询):我可能会稍后编写该查询并将其放在这里但现在..我会诚实地建议使用我上面描述的方法,除非你有每个列表中有一千个子文档。

于 2017-05-22T15:18:02.547 回答