Перейти к содержанию

ПОИСК

Ключевое слово SEARCH запускает языковую конструкцию для фильтрации представлений, ускоренную базовыми индексами. Это гарантирует использование этих индексов для эффективного плана выполнения. Если вы используете ключевое слово FILTER для представлений, индексы не используются, а фильтрация выполняется на этапе постобработки.

Концептуально, представление - это просто другой источник данных документа, подобный массиву или коллекции документов/краев, над которым вы можете выполнять итерации с помощью операции FOR в AQL:

1
2
FOR doc IN viewName
  RETURN doc

Дополнительная операция ПОИСК предоставляет возможности для:

  • фильтровать документы на основе булевых выражений и функций AQL
  • сопоставлять документы, расположенные в различных коллекциях, поддерживаемых быстрым индексом
  • сортировать набор результатов на основе того, насколько точно каждый документ соответствует условиям поиска.

О том, как настроить представления, смотрите arangosearch Views и search-alias Views.

Синтаксис

За ключевым словом SEARCH следует выражение фильтра ArangoSearch, которое в основном состоит из вызовов функций ArangoSearch AQL.

FOR doc IN viewName
  SEARCH expression
  OPTIONS { … }
  ...

Использование

Оператор SEARCH, в отличие от FILTER, рассматривается как часть операции FOR, а не как отдельный оператор. Оно не может быть свободно размещено в запросе или несколько раз в теле цикла FOR. FOR ... IN должно сопровождаться именем представления, а не коллекции. Далее должна следовать операция SEARCH, другие операции перед SEARCH, такие как FILTER, COLLECT и т.д. не допускаются в этой позиции. Последующие операции возможны после SEARCH и выражения, однако, включая SORT для упорядочивания результатов поиска на основе значения ранжирования, вычисленного представлением.

выражение должно быть выражением ArangoSearch. Вся мощь ArangoSearch используется и раскрывается с помощью специальных ArangoSearch functions, как на этапе поиска, так и на этапе сортировки. Кроме того, поддерживаются общие операторы AQL.

Обратите внимание, что встроенные выражения и некоторые другие вещи не поддерживаются SEARCH. В случае некорректного выражения сервер выдаст ошибку запроса.

Ключевое слово OPTIONS и объект могут опционально следовать за выражением поиска, чтобы задать Параметры поиска.

Логические операторы

Логические или булевы операторы позволяют объединить несколько условий поиска.

  • AND, && (конъюнкция)
  • OR, || (дизъюнкция)
  • NOT, ! (отрицание / инверсия)

Необходимо учитывать приоритет операторов Operator precedence, который можно контролировать с помощью круглых скобок.

Рассмотрим следующее надуманное выражение:

doc.value < 0 OR doc.value > 5 AND doc.value IN [-10, 10].

AND имеет более высокий приоритет, чем OR. Это выражение эквивалентно следующему:

doc.value < 0 ИЛИ (doc.value > 5 И doc.value IN [-10, 10]).

Таким образом, условия таковы:

  • значения меньше 0
  • значения больше 5, но только если оно равно 10 (или -10, но это никогда не может быть выполнено).

Чтобы применить условие AND к обоим условиям OR, можно использовать круглые скобки следующим образом:

(doc.value < 0 OR doc.value > 5) AND doc.value IN [-10, 10].

Теперь условия таковы:

  • значения меньше 0, но только если оно равно -10
  • значения больше 5, но только если оно равно 10.

Операторы сравнения

  • == (равно)
  • <= (меньше или равно)
  • >= (больше или равно)
  • < (меньше чем)
  • > (больше чем)
  • != (неравно)
  • IN (содержится в массиве или диапазоне), также NOT IN.
  • LIKE (равно с подстановочными знаками, введено в v3.7.0), также NOT LIKE.

Также смотрите функцию IN_RANGE() для альтернативы комбинации операторов <, <=, >, >= для поиска в диапазоне.

1
2
3
4
5
FOR doc IN viewName
  SEARCH ANALYZER(doc.text == "quick" OR doc.text == "brown", "text_en")
  // -- or --
  SEARCH ANALYZER(doc.text IN ["quick", "brown"], "text_en")
  RETURN doc

Алфавитный порядок символов не учитывается ArangoSearch, т.е. запросы диапазона в операциях SEARCH над представлениями не будут следовать правилам языка согласно определенной локали анализатора (кроме анализатора collation) или языку сервера (опция запуска --default-language)!

Операторы сравнения массивов

Поддерживаются Операторы сравнения массивов:

1
2
3
4
5
6
7
LET tokens = TOKENS("some input", "text_en")                 // ["some", "input"]
FOR doc IN myView SEARCH tokens  ALL IN doc.text RETURN doc // dynamic conjunction
FOR doc IN myView SEARCH tokens  ANY IN doc.text RETURN doc // dynamic disjunction
FOR doc IN myView SEARCH tokens NONE IN doc.text RETURN doc // dynamic negation
FOR doc IN myView SEARCH tokens  ALL >  doc.text RETURN doc // dynamic conjunction with comparison
FOR doc IN myView SEARCH tokens  ANY <= doc.text RETURN doc // dynamic disjunction with comparison
FOR doc IN myView SEARCH tokens NONE <  doc.text RETURN doc // dynamic negation with comparison

В выражениях ПОИСК эквивалентны следующие операторы:

  • ALL IN, ALL ==, NONE !=, NONE NOT IN.
  • ЛЮБОЙ В, ЛЮБОЙ ==
  • NONE IN, NONE ==, ALL !=, ALL NOT IN
  • ВСЕ >, НЕТ <=
  • ВСЕ >=, НЕТ <
  • ALL <, NONE >=
  • ALL <=, NONE >.

Хранимый атрибут, на который ссылается правая часть оператора, подобен единственному, примитивному значению. В случае нескольких лексем это похоже на наличие нескольких таких значений, а не на массив значений, даже если фактический атрибут документа является массивом. IN и == как часть операторов сравнения массивов, для простоты использования, рассматриваются одинаково в выражениях SEARCH. Вне SEARCH, где за IN должен следовать массив, поведение отличается.

Оператор вопросительного знака

Вы можете использовать Оператор вопросительного знака для выполнения Вложенного поиска с помощью ArangoSearch (только в версии Enterprise Edition):

1
2
3
FOR doc IN myView
  SEARCH doc.dimensions[? FILTER CURRENT.type == "height" AND CURRENT.value > 40]
  RETURN doc

Он позволяет сопоставлять вложенные объекты в массивах, которые удовлетворяют нескольким условиям каждый, и, по желанию, определять, как часто эти условия должны выполняться для всего массива. Вам необходимо настроить представление специально для этого типа поиска с помощью свойства nested в arangosearch Views или в определении Inverted Indexes, которое вы можете добавить в search-alias Views.

Обработка неиндексированных полей

Атрибуты документа, которые не настроены на индексацию в представлении, рассматриваются SEARCH как несуществующие. Это влияет только на тесты для документов, выдаваемых представлением.

Например, если дана коллекция myCol со следующими документами:

1
2
{ "someAttr": "One", "anotherAttr": "One" }
{ "someAttr": "Two", "anotherAttr": "Two" }

... с видом arangosearch, где someAttr индексируется следующим видом myView:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "type": "arangosearch",
  "links": {
    "myCol": {
      "fields": {
        "someAttr": {}
      }
    }
  }
}

... поиск по someAttr дает следующий результат:

1
2
3
FOR doc IN myView
  SEARCH doc.someAttr == "One"
  RETURN doc
1
[{ "someAttr": "One", "anotherAttr": "One" }]

Поиск по anotherAttr дает пустой результат, потому что только someAttr проиндексирован в представлении:

1
2
3
FOR doc IN myView
  SEARCH doc.anotherAttr == "One"
  RETURN doc
1
[]

При желании можно использовать специальное свойство includeAllFields arangosearch View property для индексации всех (суб-)атрибутов исходных документов.

ПОИСК с сортировкой

Документы, выдаваемые представлением, могут быть отсортированы по значениям атрибутов с помощью стандартной операции SORT(), используя один или несколько атрибутов, в порядке возрастания или убывания (или их сочетание).

1
2
3
FOR doc IN viewName
  SORT doc.text, doc.value DESC
  RETURN doc

Если (крайние левые) поля и направления их сортировки совпадают с определением primary sort order представления, то операция SORT оптимизируется.

Помимо простой сортировки, можно отсортировать сопоставленные документы Представления по баллу релевантности (или комбинации баллов и значений атрибутов, если это необходимо). Поиск документов с помощью ключевого слова SEARCH и сортировка с помощью ArangoSearch Scoring Functions, а именно BM25() и TFIDF(), тесно взаимосвязаны. Запрос, заданный в выражении SEARCH, используется не только для фильтрации документов, но и с помощью скоринговых функций решает, какой документ лучше всего соответствует запросу. Другие документы в представлении также влияют на это решение.

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

1
2
3
4
FOR doc IN viewName
  SEARCH ...
  SORT BM25(doc) DESC
  RETURN doc

Функция BOOST() может быть использована для точной настройки результирующего ранжирования путем разного взвешивания подвыражений в SEARCH.

Если перед обращением к скоринговым функциям операция SEARCH не выполняется или если поисковое выражение не отфильтровывает документы (например, SEARCH true), то для всех документов будет возвращена оценка 0.

Параметры поиска

Операция SEARCH принимает объект options со следующими атрибутами:

  • collections (массив, опционально): массив строк с именами коллекций для ограничения поиска определенными коллекциями источников.
  • conditionOptimization (string, optional): управляет тем, как оптимизируются критерии поиска. Возможные значения:
  • "auto" (по умолчанию): преобразовывать условия в дизъюнктивную нормальную форму (ДНФ) и применять оптимизацию. Удаляет избыточные или пересекающиеся условия, но может занять довольно много времени даже при небольшом количестве вложенных условий.
  • "none": поиск в индексе без оптимизации условий.
  • countApproximate (строка, опционально): определяет, как подсчитывается общее количество строк, если для запроса включена опция fullCount или выполняется условие COLLECT WITH COUNT (введено в v3.7.6).
  • "exact" (по умолчанию): строки фактически перечисляются для точного подсчета.
  • "cost": используется аппроксимация на основе затрат. Не перечисляет строки и возвращает приблизительный результат со сложностью O(1). Дает точный результат, если условие SEARCH пустое или содержит только однословный запрос (например, SEARCH doc.field == "value"), при этом обычная конечная согласованность Views отпадает.

Примеры

При наличии представления с тремя связанными коллекциями coll1, coll2 и coll3 можно вернуть документы только из первых двух коллекций и игнорировать третью, используя опцию collections:

1
2
3
FOR doc IN viewName
  SEARCH true OPTIONS { collections: ["coll1", "coll2"] }
  RETURN doc

Поисковое выражение true соответствует всем документам View. Вы можете использовать здесь любое допустимое выражение, ограничивая область поиска выбранными коллекциями источников.

Комментарии