эластичный поиск: агрегирование только определенных вложенных документов - PullRequest
0 голосов
/ 26 мая 2018

Я хочу объединить определенные вложенные документы, которые удовлетворяют данному запросу.

Позвольте мне объяснить это на примере.Я вставил в свой указатель две записи:

Первый документ:

    {
      "project": [
        {
          "subject": "maths",
          "marks": 47
        },
        {
          "subject": "computers",
          "marks": 22
        }
      ]
    }

Второй документ:

    {
      "project": [
        {
          "subject": "maths",
          "marks": 65
        },
        {
          "subject": "networks",
          "marks": 72
        }
      ]
    }

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

Я попытался запрос:

    {
      "size": 0,
      "aggs": {
        "avg_marks": {
          "avg": {
            "field": "project.marks"
          }
        }
      },
      "query": {
        "bool": {
          "must": [
            {
              "query_string": {
                "query": "project.subject:maths",
                "analyze_wildcard": true,
                "default_field": "*"
              }
            }
          ]
        }
      }
    }

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

    {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": 2,
        "max_score": 0,
        "hits": []
      },
      "aggregations": {
        "avg_marks": {
          "value": 51.5
        }
      }
    }

Мне просто нужно среднее значение по математике из данных документов, в котором ожидаемый результат составляет 56.00

любая помощь с запросомили идея будет полезна.Заранее спасибо.

1 Ответ

0 голосов
/ 27 мая 2018

Сначала вам нужно в своем отображении указать, что индекс имеет вложенное поле, как показано ниже:

PUT /nested-index {
    "mappings": {
        "document": {
            "properties": {
                "project": {
                    "type": "nested",
                    "properties": {
                        "subject": {
                            "type": "keyword"
                        },
                        "marks": {
                            "type": "long"
                        }
                    }
                }
            }
        }
    }
}

, затем вставьте свои документы:

PUT nested-index/document/1
{
    "project": [
        {
            "subject": "maths",
            "marks": 47
        },
        {
            "subject": "computers",
            "marks": 22
        }
    ]
}

, затем вставьте второй документ:

PUT nested-index/document/2
{
    "project": [
        {
            "subject": "maths",
            "marks": 65
        },
        {
            "subject": "networks",
            "marks": 72
        }
    ]
}

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

GET nested-index/_search
{
    "size": 0,
    "aggs": {
        "subjects": {
            "nested": {
                "path": "project"
            },
            "aggs": {
                "subjects": {
                    "terms": {
                        "field": "project.subject",
                        "size": 10
                    },
                    "aggs": {
                        "average": {
                            "avg": {
                                "field": "project.marks"
                            }
                        }
                    }
                }
            }
        }
    }
}

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

Так что, если у вас есть эти два документа, потому что в обоих документах выу математического субъекта среднее значение будет вычислено следующим образом:

(47 + 22 + 65 + 72) / 4 = 51,5

если вы хотите получить среднее значение для сетей, оно вернет вас (потому что в одном документеу вас есть сеть, но она будет работать со всеми значениями в массиве):

65 + 72 = 68,5

, поэтому вам необходимо использовать вложенную структуру в этом случае.

ЕслиВы заинтересованы только для одного Subjт. д. Вы можете сделать агрегацию только для предмета, равного чему-то подобного (предмет, равный «математике»):

GET nested-index/_search
{
    "size": 0,
    "aggs": {
        "project": {
            "nested": {
                "path": "project"
            },
            "aggs": {
                "subjects": {
                    "filter": {
                        "term": {
                            "project.subject": "maths"
                        }
                    },
                    "aggs": {
                        "average": {
                            "avg": {
                                "field": "project.marks"
                            }
                        }
                    }
                }
            }
        }
    }
}
...