2013-05-28 4 views
3

Я бы хотел найти массив вложенных документов и вернуть только те, которые соответствуют конкретным критериям.Возвращение частичного вложенного документа в ElasticSearch

Пример отображения будет:

{"book": 
    {"properties": 
     { 
     "title":{"type":"string"}, 
     "chapters":{ 
        "type":"nested", 
        "properties":{"title":{"type":"string"}, 
            "length":{"type":"long"}} 
            } 
        } 
      } 
    } 
} 

Так, скажем, я хочу посмотреть на главы под названием «Эпилог». Не все книги имеют такую ​​главу, но если я использую вложенный запрос, я бы получил, как результат, все главы в книге, которые имеет такую ​​главу. Хотя все, что меня интересует, это сами главы, у которых есть такой титул.

В основном я беспокоюсь о i/o и сетевом трафике, так как может быть много глав.

Также есть способ получить ТОЛЬКО вложенный документ без содержащего документа?

+0

Разве главы не всегда вложены под объект книг? – concept47

+0

Вы не можете с вложенными документами afaik.Однако вы могли бы переделать это на родительскую (книжную) связь. В этом случае ваша проблема + ответ похожа на http://stackoverflow.com/questions/7431889/how-can-i-retrieve-matching-children-only –

+1

релевантные проблемы в github, чтобы дать возможность сопоставить вложенные файлы, контекст: https://github.com/elasticsearch/elasticsearch/issues/1383 и новый https://github.com/elasticsearch/elasticsearch/issues/3022 –

ответ

4

Это очень старый вопрос, на который я наткнулся, поэтому я покажу два разных подхода к тому, как это можно обработать.

Подготовим индекс и некоторые тестовые данные первым:

PUT /bookindex 
{ 
    "mappings": { 
    "book": { 
     "properties": { 
     "title": { 
      "type": "string" 
     }, 
     "chapters": { 
      "type": "nested", 
      "properties": { 
      "title": { 
       "type": "string" 
      }, 
      "length": { 
       "type": "long" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

PUT /bookindex/book/1 
{ 
    "title": "My first book ever", 
    "chapters": [ 
    { 
     "title": "epilogue", 
     "length": 1230 
    }, 
    { 
     "title": "intro", 
     "length": 200 
    } 
    ] 
} 

PUT /bookindex/book/2 
{ 
    "title": "Book of life", 
    "chapters": [ 
    { 
     "title": "epilogue", 
     "length": 17 
    }, 
    { 
     "title": "toc", 
     "length": 42 
    } 
    ] 
} 

Теперь, когда у нас есть эти данные в Elasticsearch, мы можем получить только соответствующие хиты, используя inner_hits. Этот подход очень прост, но я предпочитаю подход, намеченный в конце.

# Inner hits query 
POST /bookindex/book/_search 
{ 
    "_source": false, 
    "query": { 
    "nested": { 
     "path": "chapters", 
     "query": { 
     "match": { 
      "chapters.title": "epilogue" 
     } 
     }, 
     "inner_hits": {} 
    } 
    } 
} 

inner_hits Вложенный запрос возвращает документы, где каждый удар содержит inner_hits объект со всеми согласующих документов, в том числе скоринговой информации. Вы можете увидеть response.

Мой предпочтительный подход к этому типу запроса заключается в использовании nested aggregation с подкатегорией filtered, которая содержит подкатегорию top_hits. Запрос выглядит следующим образом:

# Nested and filter aggregation 
POST /bookindex/book/_search 
{ 
    "size": 0, 
    "aggs": { 
    "nested": { 
     "nested": { 
     "path": "chapters" 
     }, 
     "aggs": { 
     "filter": { 
      "filter": { 
      "match": { "chapters.title": "epilogue" } 
      }, 
      "aggs": { 
      "t": { 
       "top_hits": { 
       "size": 100 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

агрегация на top_hits это один делает фактические извлечения вложенных документов и поддерживает from и size свойствами среди других. Из документации:

Если top_hits агрегатора заворачивают в nested или reverse_nested агрегатора затем вложенные хиты возвращаются. Вложенные образы находятся в скрытых мини-документах , которые являются частью обычного документа, где в сопоставлено сопоставление типа вложенного поля. Агрегатор top_hits имеет возможность скрывать эти документы, если он завернут в агрегаторе nested или reverse_nested. Подробнее о вложенном в вложенном сопоставлении типов.

The response from Elasticsearch есть (ИМО) похорошела (и, кажется, чтобы вернуть его быстрее (хотя это не научное наблюдение)) и «легче» для разбора.

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