Средневзвешенное значение для вложенной агрегации в Elastic Search

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

Я пытаюсь рассчитать средневзвешенное значение по предметам.

Мои документы имеют форму -

[{'class': '10th',
 'id': '1',
'subject': [{'marks': 60, 'name': 's1', 'weight': 30},
         {'marks': 80, 'name': 's2', 'weight': 70}]},
{'class': '11th',
 'id': '2',
'subject': [{'marks': 43, 'name': 's10', 'weight': 40},
         {'marks': 54, 'name': 's20', 'weight': 60}]},
{'class': '10th',
 'id': '3',
'subject': [{'marks': 43, 'name': 's1', 'weight': 20},
         {'marks': 54, 'name': 's20', 'weight': 80}]},
{'class': '10th',
 'id': '4',
'subject': [{'marks': 69, 'name': 's10', 'weight': 30},
         {'marks': 45, 'name': 's2', 'weight': 70}]}]

Здесь s1,s10,s2,s20 — предметы. Для данного класса, скажем, «10-й», я пытаюсь агрегировать средневзвешенное значение.

Я делаю запрос

GET students_try/_search
{
 "query": {
"match": {
  "class": "10th"
}
 },
"aggs": {
"subjects": {
  "nested": {
    "path": "subject"
  },
  "aggs": {
    "subjects": {
      "terms": {
        "field": "subject.name"
      },
      "aggs": {
        "avg_score": {
          "avg": {
            "field": "subject.marks"
          }
        },
        "weighted_grade": {
          "weighted_avg": {
            "value": {
              "field": "subject.marks"
            },
            "weight": {
              "field": "subject.weight"
            }
          }
        }
      }
    }
  }
}
  },
 "size": 0
}

Ошибка, которую я получаю, -

{u'error': {u'col': 211,
        u'line': 1,
        u'reason': u'Unknown BaseAggregationBuilder [weighted_avg]',
        u'root_cause': [{u'col': 211,
                         u'line': 1,
                         u'reason': u'Unknown BaseAggregationBuilder [weighted_avg]',
                         u'type': u'unknown_named_object_exception'}],
        u'type': u'unknown_named_object_exception'},
 u'status': 400}

Я не уверен, что вызывает ошибку.


person User54211    schedule 27.11.2018    source источник
comment
Что такое версия elasticsearch? Агрегация weighted_avg доступна в elasticsearch версии 6.4 и выше, но не в более ранних версиях.   -  person Nishant    schedule 27.11.2018
comment
хорошо, кажется, моя версия 6.2 - версия: {номер: 6.2.2, build_hash: 10b1edd, build_date: 2018-02-16T19:01:30.685723Z, build_snapshot: false, lucene_version: 7.2.1, Minimum_wire_compatibility_version: 5.6.0 , минимальная_индексная_совместимая_версия: 5.0.0},   -  person User54211    schedule 27.11.2018
comment
@NishantSaini, не могли бы вы указать мне источник / ссылку, в которой подробно описывается взвешенное_среднее значение для версии 6.4 и выше. Благодарность   -  person User54211    schedule 27.11.2018


Ответы (1)


Да, средневзвешенное значение, упомянутое Нишантом, появляется только в сообщении 6.4, как указано в разделе A few others в этом ссылка с подробным описанием версии 6.4

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

POST <your_index_name>/_search
{
  "size": 0,
  "query": {
    "match": {
      "class": "10th"
    }
  },
  "aggs": {
    "subjects": {
      "nested": {
        "path": "subject"
      },
      "aggs": {
        "subjects": {
          "terms": {
            "field": "subject.name.keyword"
          },
          "aggs": {
            "avg_score": {
              "avg": {
                "field": "subject.marks"
              }
            },
            "sum_score":{
              "sum_productOfMarksAndWeight": {
                "script": "doc['subject.marks'].value * doc['subject.weight'].value"
              }
            },
            "sum_weights": {
              "sum": {
                "field": "subject.weight"
              }
            },
            "weighted_avg":{
              "bucket_script": {
                "buckets_path": {
                  "sumScore": "sum_productOfMarksAndWeight",
                  "sumWeights": "sum_weights"
                },
                "script": "params.sumScore/params.sumWeights"
              }
            }
          }             
        }
      }
    }
  }
}

Если вы внимательно посмотрите на приведенную выше агрегацию, для каждого сегмента я рассчитал sum of weights и sum of product of weights and marks, используя Агрегация суммы, а затем я использовал эти две агрегации для расчета взвешенной агрегации.

Ниже показано, как выглядит ваш ответ. Обратите внимание, что есть предостережение, что вы также увидите sum of weights и sum of product of weights and marks в результате агрегирования.

Ответ

{
  "took": 12,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "subjects": {
      "doc_count": 6,
      "subjects": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "s1",
            "doc_count": 2,
            "sum_weights": {
              "value": 50
            },
            "sum_productOfMarksAndWeight": {
              "value": 2660
            },
            "avg_score": {
              "value": 51.5
            },
            "weighted_avg": {
              "value": 53.2
            }
          },
          {
            "key": "s2",
            "doc_count": 2,
            "sum_weights": {
              "value": 140
            },
            "sum_productOfMarksAndWeight": {
              "value": 8750
            },
            "avg_score": {
              "value": 62.5
            },
            "weighted_avg": {
              "value": 62.5
            }
          },
          {
            "key": "s10",
            "doc_count": 1,
            "sum_weights": {
              "value": 30
            },
            "sum_productOfMarksAndWeight": {
              "value": 2070
            },
            "avg_score": {
              "value": 69
            },
            "weighted_avg": {
              "value": 69
            }
          },
          {
            "key": "s20",
            "doc_count": 1,
            "sum_weights": {
              "value": 80
            },
            "sum_productOfMarksAndWeight": {
              "value": 4320
            },
            "avg_score": {
              "value": 54
            },
            "weighted_avg": {
              "value": 54
            }
          }
        ]
      }
    }
  }
}

Я надеюсь, что это поможет, дайте мне знать, если это не так, и если вы думаете, что это решает то, что вы ищете, пожалуйста, примите этот ответ ;-)

person Opster ES Ninja - Kamal    schedule 27.11.2018