Игнорировать предложение "match" из запроса в агрегации - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть запрос с агрегатами.Один из агрегатов находится на поле starsCount.Есть предложение запроса, которое фильтрует поле starsCount вместе с другими предложениями соответствия (скрыто для ясности).

Я хочу, чтобы агрегация starsCount игнорировала фильтрацию starsCount в своих результатах (Результат агрегации должен быть таким, как если бы я выполнил тот же запрос без предложения соответствия в поле starsCount), в то время как другая агрегация сохраняет свое текущее поведение

Может ли это быть сделано в одном запросе или я должен использовать несколько?

Вот (упрощенный) запрос:

{
    [...]
    "aggs": {
        "group_by_service": {
            "comment": "keep current behaviour",
            "terms": {
                "field": "services",
                "size": 46
            }
        },
        "group_by_stars": {
            "comment": "ignore the filter on the starsCount field",
            "terms": {
                "field": "starsCount",
                "size": 100
            }
        }
    },
    "query": {
        "bool": {
            "must": [
                [...] filters on other properties, non-relevant 
                {
                    "match": {
                        "starsCount": {
                            "query": "2"
                        }
                    }
                }
            ]
        }
    }
}

1 Ответ

1 голос
/ 08 апреля 2019

Да, вы можете достичь этого в одном запросе, используя постфильтр и фильтр агрегации . Чтобы создать запрос, выполните следующие действия:

  1. Удалите запрос на совпадение starsCount из основного запроса, поскольку он не должен влиять на агрегацию group_by_stars.
  2. Поскольку запрос на совпадение starsCount должен фильтровать документы, переместите его на post_filter. Любой запрос внутри post_filter будет фильтровать документы после расчета агрегации.
  3. Теперь, поскольку starsCount больше не является частью основного запроса, все агрегации не будут затронуты. Но требуется то, что этот фильтр должен влиять на все другие агрегации, кроме агрегации group_by_stars. Для достижения этого мы будем использовать агрегацию фильтров и применять ее ко всем агрегациям, кроме агрегации group_by_stars.

Результирующий запрос будет таким, как показано ниже. (Обратите внимание, что вместо запроса match я использовал запрос term. Вы все еще можете использовать совпадение, но в этом случае термин является лучшим выбором.):

{
  "aggs": {
    "some_other_agg":{
      "filter": {
        "term": {
          "starsCount": "2"
        }
      },
      "aggs": {
        "some_other_agg_filtered": {
          "terms": {
            "field": "some_other_field"
          }
        }
      }
    },
    "group_by_service": {
      "filter": {
        "term": {
          "starsCount": "2"
        }
      },
      "aggs": {
        "group_by_service_filtered": {
          "terms": {
            "field": "services",
            "size": 46
          }
        }
      }
    },
    "group_by_stars": {
      "terms": {
        "field": "starsCount",
        "size": 100
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {...} //filter on other properties
      ]
    }
  },
  "post_filter": {
    "term": {
      "starsCount": "2"
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...