ElasticSearch с фильтром через asticutils

В настоящее время я пытаюсь использовать filter в существующем экземпляре ElasticSearch через библиотеку elasticutils, К сожалению, я ничего не получаю. Я не уверен, что проблема в том, что я сделал что-то не так или в библиотеке есть проблема (вполне может быть, AFAICT).

У меня есть индекс с определенным отображением, содержащий поле (скажем, "A") типа string (без явного анализатора). Это поле всегда содержит список строк.

Я хотел бы отфильтровать документы, содержащие заданную строку в этом поле A, поэтому я попытался:

import elasticutils as eu
es = eu.S().es(urls=[ URL ]).indexes(INDEX).doctypes(DOCTYPE)
f = eu.F(A="text")
result = es.filter(f)

Но это возвращает пустой набор результатов. Я тоже пробовал это используя f = eu.F(A__in="text") но это привело к большому сообщению об ошибке, самая интригующая часть которого была [terms] filter does not support [A],

Мне интересно, если я должен настроить свой индекс по-другому, может быть, мне нужно создать фасет, чтобы иметь возможность использовать фильтр? Но я не нашел намека на это в документации, которую прочитал.

Моя причина желания использовать filter является то, что они могут свободно комбинироваться с помощью and, or, а также not, Я также нашел некоторые спецификации, описывающие, что query также может быть логическим, но они обычно относятся к must, should, а также must_not которые не достаточно гибки для меня, я думаю. Но я также нашел некоторые спецификации, которые упоминали operator флаг для querys, которые можно установить на and или же or, Любая информация об этом приветствуется.

Итак, мои вопросы сейчас:

  • Это проблема конфигурации? Есть ли у фасетов какое-то отношение к этому?
  • Я хотел бы проверить, является ли это ошибкой библиотеки, пропустив библиотеку, так как я могу выполнить это действие фильтрации, используя, скажем, curl? Или любая другая библиотека (может быть pyes)?
  • Является гибким сочетанием (используя and, or, notи возможна ли их группировка по нескольким запросам (т.е. вообще без использования фильтров)? Как бы я это сделал? (Желательно в elasticutils но другие библиотечные синтаксисы, например pyesили простые CURL также приветствуются).

2 ответа

Решение

airza ударил по голове своим ответом в виде фильтра, который вы ищете, в формате CURL. Я подозреваю, что проблемы, которые вы видите, в основном связаны с использованием модуля абстракции, такого как elasticutils - было бы хорошо сначала ознакомиться с базовым протоколом запросов ES. Это сделает понимание elasticutils Полегче. Как и в моем комментарии выше, я рекомендую установить Sense, плагин для Google Chrome, который позволит вам легко запрашивать кластер ES: https://chrome.google.com/webstore/detail/sense/doinijnbnggojdlcjifpdckfokbbfpbo?hl=en.

Фильтры запросов Elasticsearch чрезвычайно гибкие и "встраиваемые". Вы можете довольно легко вложить or фильтр внутри boolmust фильтр. Пример:

{
    "query": {
        "filtered": {
           "query": {
               "match_all": {}
           },
           "filter": {
               "bool": {
                   "must": [
                       {
                           "or": [
                                 {"exists": {"field": "sessions"}},
                                 {"range": {"id": {"gte": 56000}}}
                           ]
                       },
                       {
                           "term": {"age_min": "13"}
                       }
                   ],
                   "should": [
                      {
                          "term": {"area": "1"}
                      }
                   ]
               }
           }
        }
    }
}

В этом примере результаты должны соответствовать одному из двух mustor фильтры и тому age_minterm фильтр и элементы, соответствующие areaterm фильтр в should пункт будет выше, чем несоответствующие элементы.

Запрос CURL для решения этой проблемы довольно прост:

curl -XPOST URL/INDEX/_search? -d '{
  "filter": {
    "term": {
      "A": "val"
    }
  }
}'

Здесь нет особой связи с фасетами (это тип поискового запроса, который используется для получения размера различных подмножеств другого запроса), но если поле A не проиндексировано, вы не сможете его найти и что-нибудь найти. ОДНАКО, если это так, ваш запрос ES должен просто возвращать любые записи (поскольку, когда вы запрашиваете неиндексированное поле, вы, по сути, не даете ES никаких особых инструкций по фильтрации).

Запрос, выдвинутый моей попыткой выполнить эквивалентный поиск ES с использованием этой библиотеки, был следующим:

{'filter': {'term': {'language': 'EN'}

То, что вы видите, совпадает с тем, которое вы запускали. Что случилось, когда вы вызвали result.all()?

Другие вопросы по тегам