Вложенный фильтр в запросе агрегирования Elasticsearch

Я выполняю следующий агрегационный запрос с вложенным фильтром

GET <indexname>/_search
{
  "aggs": {
    "NAME": {
      "nested": {
        "path": "crm.LeadStatusHistory"
      },
      "aggs": {
        "agg_filter": {
          "filter": {
            "bool": {
              "must": [
                {
                  "nested": {
                    "path": "crm",
                    "query": {
                      "terms": {
                        "crm.City.keyword": [
                          "Rewa"
                        ]
                      }
                    }
                  }
                },
                {
                  "nested": {
                    "path": "crm",
                    "query": {
                      "terms": {
                        "crm.LeadID": [
                          27961
                        ]
                      }
                    }
                  }
                }
              ]
            }
          },
          "aggs": {
            "agg_terms":{
              "terms": {
                "field": "crm.LeadStatusHistory.StatusID",
                "size": 1000
              }
            }
          }
        }
      }
    }
  }
}

-----> У меня есть следующий документ

{
        "_index" : "crm",
        "_type" : "_doc",
        "_id" : "4478",
        "_score" : 1.0,
        "_source" : {
          "crm" : [
            {
              "LeadStatusHistory" : [
                {
                  "StatusID" : 3
                },
                {
                  "StatusID" : 2
                },
                {
                  "StatusID" : 1
                }
              ],
              "LeadID" : 27961,
              "City" : "Rewa"
            },
            {
              "LeadStatusHistory" : [
                {
                  "StatusID" : 1
                },
                {
                  "StatusID" : 3
                },
                {
                  "StatusID" : 2
                }
              ],
              "LeadID" : 27959,
              "City" : "Rewa"
            }
          ]
        }
      }]

Однако в ответ я получаю следующий результат

"aggregations" : {
    "NAME" : {
      "doc_count" : 4332,
      "agg_filter" : {
        "doc_count" : 1,
        "agg_terms" : {
          "doc_count_error_upper_bound" : 0,
          "sum_other_doc_count" : 0,
          "buckets" : [
            {
              "key" : 1,
              "doc_count" : 1
            }
          ]
        }
      }
    }
  }

Запрос ===> Согласно исходному документу у меня есть 3 вложенных документа crm.LeadStatusHistory для crm.LeadID = 27961. Однако результаты показывают, что agg_filter равен 1 вместо 3. Не могли бы вы сообщить мне причину этого кейс.


person Ankur Agarwal    schedule 08.01.2020    source источник
comment
Пожалуйста, поделитесь своими сопоставлениями.   -  person LeBigCat    schedule 08.01.2020
comment
Привет, LeBigCat, дайте нам знать конкретные вопросы, так как совместное использование карт невозможно. Я поделился исходным документом для вашей справки   -  person Ankur Agarwal    schedule 09.01.2020


Ответы (2)


Ваш agg_filter находится в crm.LeadStatusHistory => будет нацелен только на 1 документ (LeadStatusHistory - это один документ, содержащий в вашем случае ссылку на другие документы).

Я создаю запрос, который это покажет, и я думаю, что отвечу на вашу проблему. Вы увидите разные doc_count для каждой агрегации.

{
  "size": 0,
  "aggs": {
    "NAME": {
      "nested": {
        "path": "crm"
      },
      "aggs": {
        "agg_LeadID": {
          "terms": {
            "field": "crm.LeadID"
          },
          "aggs": {
            "agg_LeadStatusHistory": {
              "nested": {
                "path": "crm.LeadStatusHistory"
              },
              "aggs": {
                "home_type_name": {
                  "terms": {
                    "field": "crm.LeadStatusHistory.StatusID"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

с этим вы можете подсчитать их с помощью скрипта (и при необходимости отфильтровать):

{
  "size": 0,
  "aggs": {
    "NAME": {
      "nested": {
        "path": "crm"
      },
      "aggs": {
        "agg_LeadID": {
          "terms": {
            "field": "crm.LeadID"
          },
          "aggs": {
            "agg_LeadStatusHistory": {
              "nested": {
                "path": "crm.LeadStatusHistory"
              },
              "aggs": {
                "agg_LeadStatusHistory_sum": {
                  "sum": {
                    "script": "doc['crm.LeadStatusHistory.StatusID'].values.length"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

примечание: если вы хотите узнать количество вложенных документов, посмотрите inner_hits: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-inner-hits

person LeBigCat    schedule 09.01.2020

Я не согласен с ответом, что в crm.LeadStatusHistory находится один документ. Я выполнил агрегационный запрос на crm.LeadstatusHistory без фильтров.

GET crm/_search
{
  "_source": ["crm.LeadID","crm.LeadStatusHistory.StatusID","crm.City"], 
  "size": 10000,
  "query": {
    "nested": {
      "path": "crm",
      "query": {
        "match": {
          "crm.LeadID": "27961"
        }
      }
    }
  }, 
  "aggs": {
    "agg_statuscount": {
      "nested": {
        "path": "crm.LeadStatusHistory"
      },
          "aggs": {
            "agg_terms":{
              "terms": {
                "field": "crm.LeadStatusHistory.StatusID",
                "size": 1000
              }
            }
          }
        }
      }
    }

Я получаю следующий ответ на запрос выше, который показывает "agg_statuscount" как 6 документов без фильтров.

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "crm",
        "_type" : "_doc",
        "_id" : "4478",
        "_score" : 1.0,
        "_source" : {
          "crm" : [
            {
              "LeadStatusHistory" : [
                {
                  "StatusID" : 3
                },
                {
                  "StatusID" : 2
                },
                {
                  "StatusID" : 1
                }
              ],
              "LeadID" : 27961,
              "City" : "Rewa"
            },
            {
              "LeadStatusHistory" : [
                {
                  "StatusID" : 1
                },
                {
                  "StatusID" : 3
                },
                {
                  "StatusID" : 2
                }
              ],
              "LeadID" : 27959,
              "City" : "Rewa"
            }
          ]
        }
      }
    ]
  },
  "aggregations" : {
    "agg_statuscount" : {
      "doc_count" : 6,
      "agg_terms" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [
          {
            "key" : 1,
            "doc_count" : 2
          },
          {
            "key" : 2,
            "doc_count" : 2
          },
          {
            "key" : 3,
            "doc_count" : 2
          }
        ]
      }
    }
  }
}

Следовательно, с crm.LeadID = 27961 в фильтре агрегации я ожидал 3 документа crm.LeadStatusHistory. В настоящее время ответ - 1, как и в моем исходном вопросе.

person Ankur Agarwal    schedule 10.01.2020