Агрегирование количества документов с помощью запроса в Elasticsearch (например, facet.query в solr)

У меня есть основной запрос, и мне нужно количество совпадений для пары подзапросов. Другими словами, мне нужен facet.query. Чего мне не хватает, так это простой doc_count агрегации, такой как агрегация value_count.

Какие-либо предложения?

Я нашел два возможных решения, которые мне не нравятся:

  1. Используйте агрегацию фильтров с показателем value_count. на _id:

пример:

GET _search
{
    "query": {
        "match_main": {}
    },
    "aggs": {
            "facetvalue1": {
                "filter": {
                     "bool": { 
                    "should": [
                      {"match": { "name": "fred" }},
                      {"term": { "lastname": "krueger" }}
                     ]
                     }
                },
                "aggs": {
                    "count": {
                        "value_count": {
                            "field": "_id"
                        }
                    }
                }
            },
            "facetvalue2": {
                "filter": {
                      "term": { "name": "freddy" }
                },
                "aggs": {
                    "count": {
                        "value_count": {
                            "field": "_id"
                        }
                    }
                }
            }
    }
}
  1. Используйте API мультипоиска.

пример:

GET _msearch
{"index":"myindex"}
{"query":{"match_main": {}}}
{"index":"myindex"}
{"size": 0, "query":{"match_main": {}}, "filter": {"bool": {"should":[{"match": { "name": "fred" }},{"term": { "lastname": "krueger" }}]}}}
{"index":"myindex"}
{"size": 0, "query":{"match_main": {}},"filter": {"term": { "name": "freddy" }}}

Я вижу, что решение 2 быстрее, но представьте match_main как сложный запрос! Поэтому я бы предпочел решение 1, если бы вместо value_count:{"field":"_id"} было doc_count:{}.

Но вернемся к моему основному вопросу: что является аналогом solr facet.query в elasticsearch?


person Karsten R.    schedule 30.06.2016    source источник


Ответы (1)


Вы можете использовать filters aggregation для этого. Обратите внимание на дополнительную s, которая отличается от уже упомянутой вами агрегации filter.

{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "values": {
      "filters": {
        "filters": {
          "value1": {
            "bool": {
              "should": [
                {
                  "match": {
                    "name": "fred"
                  }
                },
                {
                  "term": {
                    "lastname": "krueger"
                  }
                }
              ]
            }
          },
          "value2": {
            "term": {
              "name": "freddy"
            }
          }
        }
      }
    }
  }
}

Это вернет что-то вроде

"aggregations": {
  "values": {
    "buckets": {
      "value1": {
        "doc_count": 4
      },
      "value2": {
        "doc_count": 1
      }
    }
  }
}

Изменить. Как правило, вам не нужно использовать агрегацию метрик в агрегациях корзин. Если вы не предоставите какие-либо подагрегации, вы просто получите количество документов. В этом случае сегменты будут предоставлены filters, но также должны работать несколько агрегаций filter.

person knutwalker    schedule 30.06.2016
comment
В дополнение к вашему примечанию: если вы используете объединения показателей верхнего уровня (которые не показывают количество документов, как это делают объединения сегментов), но вам нужен документ count, вы можете встроить свои агрегаты показателей в filter Агрегация сегментов. Таким образом, вы получаете количество документов, даже если не используете ведра. Пример: filter: { match_all: {} }, aggs: { sum: { ... }}. Кстати: не используйте hits.total.value, он ограничен 10K - person maganap; 11.04.2021