2015-04-01 2 views
1

Как удалить подпункты из документа. Так что скажите, что у меня есть документ, называемый продажами, с каждой продажей есть sale.item, который содержит {имя, цена, код}.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

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. К сожалению, способ, которым это работает, состоит в том, чтобы сделать копию списка «предметов» внутри вашего конкретного «документа», с которым вы в настоящее время имеете дело, но копия имеет недокапитал, который вам не нравится, удален из списка «items» , Эта новая копия списка заменяет старую копию списка элементов.

Существует еще один, самый эффективный способ удаления субдокументов из списка - и это путем доступа к определенной ячейке списка с элементами [2] - и вам нужно использовать функции fancy array даже более привлекательные, чем тот, который я используемый здесь, чтобы узнать конкретную ячейку в списке (будь то [2] или [3] или [567]), а затем заменить содержимое этой ячейки Null, используя команду UPDATE, а затем установить параметры KeepNull = false. Это «самый эффективный» способ сделать это, но это будет чудовищно выглядящий сложный запрос): я мог бы написать этот запрос позже и поместить его сюда, но прямо сейчас. Я бы честно предложил использовать метод, описанный выше, если у вас нет тысячи поддокументов в каждом списке.