2016-01-22 3 views
4

Я новичок в Elasticsearch, и я пытаюсь создать фильтр для извлечения документов, имеющих определенные атрибуты.Фильтр вложенных объектов Elasticsearch

атрибуты определяются как вложенные объекты в отображении так:

"attributes": { 
    "type": "nested", 
    "properties" : { 
     "id": { 
     "type": "integer" 
     }, 
     ... 
    } 
    } 
} 

Я пытаюсь выполнить сложный запрос в виде:

(attribute.id == 1 OR attribute.id == 2) AND (attribute.id == 3 OR attribute.id == 4) 

Согласно тому, что я имею прочитайте до сих пор. Я создал следующий запрос к:

{ 
    "query": { 
    "filtered": { 
    "query": { 
     "match_all": {} 
    }, 
    "filter": { 
     "nested": { 
      "path": "attributes", 
      "filter": { 
       "bool": { 
       "must": [ 
        { "bool" : { 
         "should" : [ 
         { "term": { "attributes.id": 1 }}, 
         { "term": { "attributes.id": 2 }} 
         ] 
        }}, 
        { "bool" : { 
         "should" : [ 
         { "term": { "attributes.id": 3 }}, 
         { "term": { "attributes.id": 4 }} 
         ] 
        }} 
       ] 
       } 
      } 
     } 
    } 
    } 
}, 
"sort": { 
    "date": { "order": "desc" } 
    } 
} 

Однако это не возвращает никакой информации, зультаты. Если я удалю один из двух bools в блоке must, он правильно фильтрует документы.

Такая же проблема существует (без результатов), если изменить запрос (для тестирования) по адресу:

"must": [ 
    { "term": { "attributes.id": 3 }}, 
    { "bool" : { 
    "should" : [ 
     { "term": { "attributes.id": 1 }}, 
     { "term": { "attributes.id": 2 }} 
    ] 
    }} 
] 

для моего понимания переводит к attributes.id == 3 AND (attributes.id == 1 OR attributes.id == 2)

Это elasticsearch 2.x. Что я делаю неправильно?

+0

Возможно, каждая статья 'bool' может быть в своем собственном« вложенном »предложении? Вместо того, чтобы все это было обернуто в одном. –

+0

@EvaldasBuinauskas Я попробую и вернусь к вам. – mobius

+0

Можете ли вы разместить образец документа, который вы ожидаете получить от этого запроса? – goalie7960

ответ

3

Для того, чтобы найти то, что вы ищете, вам нужно сделать два отдельных запроса nested и связать их с запросом bool.

Вот пример:

{ 
    "bool":{ 
    "must":[ 
     { 
     "nested":{ 
      "path":"attributes", 
      "filter":{ 
      "bool":{ 
       "should":[ 
       { "term": {"attributes.id": 1 }}, 
       { "term": {"attributes.id": 2 }} 
       ] 
      } 
      } 
     } 
     }, 
     { 
     "nested":{ 
      "path":"attributes", 
      "filter":{ 
      "bool":{ 
       "should":[ 
       { "term": {"attributes.id": 3 }}, 
       { "term": {"attributes.id": 4 }} 
       ] 
      } 
      } 
     } 
     } 
    ] 
    } 
} 

Причина этого связана с тонким оттенком с вложенными документами и вложенными запросами. Посмотрите на части documentation on nested queries, который говорит:

запрос выполняется в отношении вложенных объектов/документы, как если бы они были проиндексированы как отдельные документы (они, внутренне), и в результате корень родительского doc (или родительское вложенное сопоставление).

При выполнении nested запроса, вы на самом деле не выполняет запрос от корневого документа (хотя чувствует что путь). Запрос работает против вложенных документов , как если бы они были отдельными документами.

Таким образом, при запросе для вложенного документа, который имеет как идентификатор = (1 или 2) и Ид = (3 или 4), вы не получите никаких результатов. Каждый вложенный документ, по вашим данным, имеет только одно из этих значений id.

+0

Вы абсолютно правы! (как @EvaldasBuinauskas указал в комментариях выше). Что меня больше смущает, так это то, что наличие одного должно быть в духе. – mobius

+0

Большое спасибо. Это действительно ясно. Большая помощь. –

Смежные вопросы