2015-04-01 58 views
1
中刪除子項

如何從文檔中刪除子項。所以說我有一個叫做銷售的文檔,每個銷售都有一個sale.item,它包含{name,price,code}。Arangodb從文檔

我想刪除無效的每個項目,通過檢查代碼爲空或空。

嘗試類似下面的錯誤,不知道是否需要使用子查詢和如何。

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 

回答

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

太棒了,沒有想到用這種方式解決問題。你搖滾,紙,剪刀:) – iswak 2015-04-01 18:54:12

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命令的一部分。不幸的是,它的工作方式是在當前正在處理的特定「文檔」中製作「項目」列表的副本,但該副本包含您不喜歡的子文檔,從「項目」列表中刪除。該列表的新副本將替換項目列表的舊副本。

還有一種更有效的方法來從列表中刪除子文檔 - 也就是通過訪問列表中特定的單元格[2] - 並且必須使用花式數組函數,甚至比我更有趣在這裏使用,找出列表中的特定單元格(無論是[2]還是[3]或[567]),然後使用UPDATE命令將該單元格的內容替換爲Null,然後設置選項KeepNull = false。這是做到這一點的「最有效的」方式,但它會是一個看起來很複雜的查詢):我可能會稍後再寫這個查詢,然後把它放在這裏,但現在我真的會建議使用我上面描述的方法,除非你有每個列表中有一千個子文檔。