2013-07-26 3 views
1

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

У меня есть индекс со специфическим отображением, содержащий поле (скажем, «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 для query s, который может быть установлен на and или or. Любая информация по этому поводу приветствуется.

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

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

Могу ли я предложить вам взглянуть на плагин Sense (https://chrome.google.com/webstore/detail/sense/doinijnbnggojdlcjifpdckfokbbfpbo?hl=ru) для Chrome? Это отличный инструмент для работы с кластером ES, а не с CURL. Кроме того, я бы рекомендовал начинать с поиска пиеловатиков, а не с того, что кажется слишком абстрактным - по крайней мере, для начала (http://pyelasticsearch.readthedocs.org/). :) –

+0

Я не очень хорошо знаю эту библиотеку - есть ли способ увидеть JSON, который он использует для запроса ES? – argentage

ответ

3

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

Фильтры запросов Elasticsearch: чрезвычайно гибкий - и 'nestable'. Вы можете легко вложить фильтр 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 будет рангом выше, чем не совпадающие элементы ,

+0

Спасибо за подробный ответ и пример, в котором сочетаются фильтры и запросы, в этом мне очень полезно. Я тоже использую прямой скручивание, хотя я не рад потерять все красивые абстракции, которые предоставляет библиотека 'elasticutils'. Может быть, я узнаю, как пинать этот lib, чтобы он делал то, что я хочу в будущем, но в настоящее время я придерживаюсь уверенности, что это не проблема. – Alfe

+0

Я отошел от абстракций (например, django-haystack) в пользу чего-то более прямого, чем «pyelasticsearch», чтобы добиться большей гибкости. Абстракции велики, пока они не станут. :) –

1

локонов запрос, чтобы решить эту проблему довольно просто:

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

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

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

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

Который вы видите, тот же, что и тот, с которым вы бежали. Что произошло, когда вы вызвали result.all()?