Как выполнить агрегирование `sum` и` avg`, даже если сопоставления полей относятся к типам `text` и` keyword`? - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь выполнить агрегацию sum и avg для моего запроса Elasticsearch, все отлично работает, но я столкнулся с проблемой - я хочу выполнить вышеупомянутые агги для моих полей nested, которыена text / keyword типов.

Причина, по которой они таковы, заключается в том, что мы будем использовать анализатор keywords при выполнении API search, если требуются эти конкретные вложенные поля и подполя.

Вот мое отображение:

"eng" : {
  "type" : "nested",
  "properties" : {
    "date_updated" : {
      "type" : "long"
    },
    "soc_angry_count" : {
      "type" : "float"
    },
    "soc_comment_count" : {
      "type" : "float"
    },
    "soc_dislike_count" : {
      "type" : "float"
    },
    "soc_eng_score" : {
      "type" : "float"
    },
    "soc_er_score" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "soc_haha_count" : {
      "type" : "float"
    },
    "soc_kf_score" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "soc_like_count" : {
      "type" : "float"
    },
    "soc_love_count" : {
      "type" : "float"
    },
    "soc_mm_score" : {
      "type" : "float"
    },
    "soc_sad_count" : {
      "type" : "float"
    },
    "soc_save_count" : {
      "type" : "float"
    },
    "soc_share_count" : {
      "type" : "float"
    },
    "soc_te_score" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "soc_view_count" : {
      "type" : "float"
    },
    "soc_wow_count" : {
      "type" : "float"
    }
  }
}

Пожалуйста, обратите внимание на подполя soc_er_score, soc_kf_score и soc_te_score вложенного поля eng ...

Когда я 'м, выполняя следующие агги, все работает нормально:

'aggs' => [
    'ENGAGEMENT' => [
        'nested' => [
            'path' => "eng"
        ],
        'aggs' => [
            'ARTICLES' => [
                //Use Histogram because the pub_date is of
                //long data type
                //Use interval 86400 to represent 1 day
                'histogram' => [
                    'field'  => "eng.date_updated",
                    "interval" => "86400",
                ],
                'aggs'= [
                    'SUM' => [
                        'sum' => [
                            "field" => "eng.soc_like_score"
                        ]
                    ]
                ]
            ]
        ]
    ]
]

Вот вывод после выполнения search API

enter image description here

НО если запрос выглядит так:

'aggs' => [
    'ENGAGEMENT' => [
        'nested' => [
            'path' => "eng"
        ],
        'aggs' => [
            'ARTICLES' => [
                //Use Histogram because the pub_date is of
                //long data type
                //Use interval 86400 to represent 1 day
                'histogram' => [
                    'field'  => "eng.date_updated",
                    "interval" => "86400",
                ],
                'aggs'= [
                    'SUM' => [
                        'sum' => [
                            "field" => "eng.soc_te_score"
                        ]
                    ]
                ]
            ]
        ]
    ]
]

Вывод выглядит так:

enter image description here

РЕШЕНИЯ ВЫПОЛНЕНЫ

РЕШЕНИЕ 1 (для подтверждения)
Прочитав некоторые подробные обсуждения на форуме, я узнал, что синтаксический анализ на основе Java доступен, но, похоже,не работает на моем конце

Вот мой пересмотренный запрос:

'aggs'= [
    'SUM' => [
        'sum' => [
            "field" => "Float.parseFloat(eng.soc_te_score).value"
        ]
    ]
]

Но, к сожалению, он отвечает null или 0 values

enter image description here

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

Просьба о помощи, пожалуйста, заранее спасибо!

Ответы [ 2 ]

1 голос
/ 02 октября 2019

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

Например, измените свое отображение следующим образом:

"soc_er_score" : {
  "type" : "text",
  "fields" : {
    "keyword" : {
      "type" : "keyword",
      "ignore_above" : 256
    },
    "numeric" : {
      "type" : "long",
      "ignore_malformed": true
    }
  }
},

Затем вы можете использовать:

  • soc_er_score для полнотекстового поиска
  • soc_er_score.keyword для сортировки, агрегирования терминов и точного соответствия
  • soc_er_score.numeric для sum и других метрических агрегаций.

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

PUT my-index/_mapping/doc
{
  "properties": {
    "eng": {
      "soc_er_score" : {
        "type" : "text",
        "fields" : {
          "keyword" : {
            "type" : "keyword",
            "ignore_above" : 256
          },
          "numeric" : {
            "type" : "long",
            "ignore_malformed": true
          }
        }
      }
    }
  }
}

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

POST my-index/_update_by_query

Когда все будет готово, поле eng.soc_er_score.numeric будет проиндексировано для всех ваших существующих документов.

0 голосов
/ 02 октября 2019

Я смог решить мою проблему с помощью следующего простого сценария:

"aggs" = [
    'SUM' => [
        'sum' => [
            "script" => "Float.parseFloat(doc['eng.soc_te_score.keyword'].value)"
        ]
    ]
];

При этом, даже если мое вложенное поле имеет тип text и keyword, я все еще могу вычислить их Среднее и Сумма

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...