Отфильтрованный результат агрегации Elasticsearch не работает должным образом

  1. два образца документов

ПОСТ /aggstest/тест/1

{
    "categories": [
        {
            "type": "book",
            "words": [
                {"word":"storm","count":277},
                {"word":"pooh","count":229}
            ]
        },
        {
            "type": "magazine",
            "words": [
                {"word":"vibe","count":100},
                {"word":"sunny","count":50}
            ]
        }
    ]
}

ПОСТ /aggstest/тест/2

{
    "categories": [
        {
            "type": "book",
            "words": [
                {"word":"rain","count":160},
                {"word":"jurassic park","count":150}
            ]
        },
        {
            "type": "megazine",
            "words": [
                {"word":"tech","count":200},
                {"word":"homes","count":30}
            ]
        }
    ]
}
  1. аггс-запрос

ПОЛУЧИТЬ /aggstest/test/_search

{
  "size": 0,
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "categories.type": "book"
              }
            },
            {
              "term": {
                "categories.words.word": "storm"
              }
            }
          ]
        }
      }
    }
  },
  "aggs": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "categories.type": "book"
              }
            }
          ]
        }
      },
      "aggs": {
        "book_category": {
          "terms": {
            "field": "categories.words.word",
            "size": 10
          }
        }
      }
    }
  },
  "post_filter": {
    "term": {
      "categories.type": "book"
    }
  }
}
  1. результат

    {  
       "took": 5,  
       "timed_out": false,
       "_shards": {
          "total": 5,
          "successful": 5,
          "failed": 0
       },
       "hits": {
          "total": 1,
          "max_score": 0,
          "hits": []
       },
       "aggregations": {
          "filtered": {
             "doc_count": 1,
             "book_category": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [
                   {
                      "key": "pooh",
                      "doc_count": 1
                   },
                   {
                      "key": "storm",
                      "doc_count": 1
                   },
                   {
                      "key": "sunny",
                      "doc_count": 1
                   },
                   {
                      "key": "vibe",
                      "doc_count": 1
                   }
                ]
             }
          }
       }
    }
    

========================

Ожидаемый набор результатов aggs не должен включать «солнечный» и «вибрационный», потому что это тип «журнала».

Я использовал запрос фильтра и post_filter, но я не мог получить только результат типа «книга».


person Youngjun Kim    schedule 08.05.2015    source источник
comment
Почему вы фильтруете внутри агрегатов? Попробуйте "aggs" : { "agg_name" : { "terms" : " { "field" : "categories.words.words" } } }   -  person Mave    schedule 08.05.2015


Ответы (1)


Все фильтры, которые вы применяете (в запросе и в агрегации), по-прежнему возвращают весь categories документ. И этот документ, содержащий все 4 слова, является областью для агрегации. Следовательно, вы всегда получаете все 4 ведра. Насколько я понимаю, какой-то способ манипулирования сегментами на стороне сервера будет представлен с помощью редьюсеров в версии 2.0 Elasticsearch.

Теперь вы можете изменить сопоставление так, чтобы categories было вложенный объект. Следовательно, вы сможете запрашивать их независимо и соответствующим образом агрегировать, используя вложенную агрегацию. Изменение типа объекта на вложенный требует переиндексации.

Также обратите внимание, что пост-фильтры вообще не применяются к агрегации. Они используются для фильтрации исходного запроса, не влияя на агрегацию, когда вам нужно агрегировать более широкую область, чем возвращенные обращения.

И еще одно, если у вас уже есть фильтр в запросе, нет необходимости помещать его в агрегацию, область действия уже отфильтрована.

person tiurin    schedule 08.05.2015
comment
Х Тюрини. Я работаю с Ёнджун Ким. Спасибо за советы. У нас были все эти фильтры, потому что мы пробовали все! Мы не хотим использовать вложенные объекты, потому что это создаст слишком много документов... ~ 3000 на документ «верхнего уровня», то есть триллионы. У Lucene есть ограничение на количество документов на шард... Я думаю, 1,5 миллиарда. В любом случае, если это так, я думаю, мы поместим категории в их собственные объекты (всего около 5 категорий)... например, вместо категорий.тип=книга, просто объект книги. Согласны ли вы, что это правильный путь, учитывая дополнительную информацию, которую я предоставил? - person Darby; 08.05.2015