Когда я должен использовать UNNEST vs ANY ... SATISFIES в N1ql? - PullRequest
1 голос
/ 24 апреля 2019

Я хочу запросить (или проиндексировать) поле со значением массива.

В качестве примера, скажем, я хочу получить этот документ { "myarray": [ 1, 2, 3]}.

Я могу сделать это с ANY...SATISFIES или с UNNEST. Из документации они кажутся функционально одинаковыми.

SELECT * FROM `bucket` AND ANY v in myarray SATISFIES v=3 END;

SELECT * FROM `bucket` UNNEST myarray v WHERE v=3

Каковы варианты использования для каждого?

Ответы [ 2 ]

2 голосов
/ 24 апреля 2019

Первый - предикат внутри документа, а результаты запроса - документы из "корзины". Второй выполняет объединение каждого документа в «корзине» со значениями в «myarray», и каждый результат запроса является копией документа в «корзине» и одним значением из «myarray».

Вообще говоря, ожидайте, что второй вариант будет намного дороже.

2 голосов
/ 24 апреля 2019

Для этих двух запросов они выполняют сходные функции, но оба эти подхода предоставляют другие функциональные возможности.

Фактические результаты обоих этих запросов должны быть разными.Первый запрос вернет данные массива как есть, а UNNEST сгладит массив.

UNNEST - это соединение внутри документа.Удовлетворение позволяет вам (как вы сделали), проверить массив, чтобы увидеть, соответствует ли он некоторым критериям, но он на самом деле не преобразует массив в результатах.

Обновление :

Это не обязательно вопрос «что лучше».Оба этих запроса делают разные вещи.Предположим, ваш документ выглядит следующим образом:

{
  "foo": "bar",
  "myarray": [
    1,
    2,
    3
  ]
}

Теперь давайте предположим, что вы удалили WHERE из обоих этих запросов.

Затем запустите этот запрос:

SELECT d.foo, d.myarray, v
FROM `demo` d
UNNEST d.myarray v

Вы получаете 3 результата, потому что происходит соединение.Например:

[
{"foo":"bar","myarray":[1,2,3],"v":1},
{"foo":"bar","myarray":[1,2,3],"v":2},
{"foo":"bar","myarray":[1,2,3],"v":3}
]

С другим запросом:

SELECT d.*
FROM `demo` d

Вы получите один результат, потому что соединение не происходит.Это предикат внутри документа, но не соединение внутри документа.

[{"foo":"bar","myarray":[1,2,3]}]

Какую из них использовать?Вообще говоря, это зависит от вашего варианта использования.Переполнение стека не для того, чтобы дать такой специфический совет лазера.Если вы просто не торопитесь, я бы порекомендовал протестировать обе ваши реальные данные, чтобы увидеть, какие из них более эффективны (ваш пример документа, вероятно, не является вашим реальным документом).

Индексирование также являетсяфактор .Опять же, основываясь только на вашем примере документа, для запроса SATISFIES вы, вероятно, создадите такой индекс:

CREATE INDEX adv_DISTINCT_myarray ON `demo`(DISTINCT `myarray`)

А для запроса UNNEST вы, вероятно, создадите такой индекс:

CREATE INDEX adv_ALL_myarray ON `demo`(ALL `myarray`)

Эти индексы предполагают, что все, что вы делаете, проверяет myarray на единственное значение.Если ваши реальные запросы более сложны, вам понадобится более сложный индекс.

Еще одно примечание: за кулисами в обработчике запросов я понятия не имею, какова разница в реализации, поэтому я быпойти на совет Йохана о том, что UNNEST дороже.Но ваш пробег может отличаться, поэтому я бы порекомендовал попробовать оба варианта и сделать несколько тестов.

...