Серия Elasticsearch --- агрегирующий запрос (1)

Elasticsearch

резюме

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

Основные понятия

bucket

Группировка данных, некоторые данные разбиваются на корзины по определенному полю, а данные с одинаковым значением поля помещаются в корзинку. Его можно понимать как структуру Map в Java, которая похожа на результат запроса после группировки в Mysql.

метрика:

Статистические данные, выполняемые по группе данных, такие как расчет максимума, минимума, среднего значения и т. д. Подобно значениям функций max(), min() и avg() в Mysql, все они используются после группировки.

кейс

Возьмем за основу английскую потешку и рассмотрим структуру индекса:

PUT /music
{
  "mappings": {
      "children": {
        "properties": {
          "id": {
            "type": "keyword"
          },
          "author_first_name": {
            "type": "text",
            "analyzer": "english"
          },
          "author_last_name": {
            "type": "text",
            "analyzer": "english"
          },
          "author": {
            "type": "text",
            "analyzer": "english",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "content": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "language": {
            "type": "text",
            "analyzer": "english",
            "fielddata": true
          },
          "tags": {
            "type": "text",
            "analyzer": "english"
          },
          "length": {
            "type": "long"
          },
          "likes": {
            "type": "long"
          },
          "isRelease": {
            "type": "boolean"
          },
          "releaseDate": {
            "type": "date"
          }
        }
      }
  }
}

Статистика того, на каком языке в настоящее время включено больше всего песен

GET /music/children/_search
{
  "size": 0,
  "aggs": {
    "song_qty_by_language": {
      "terms": {
        "field": "language"
      }
    }
  }
}

Объяснение синтаксиса:

  • size: 0 означает, что пока будут получены статистические результаты, исходные данные отображаться не будут.
  • aggs: фиксированный синтаксис, aggs должен быть объявлен для анализа агрегации
  • song_qty_by_language: Название агрегации, можно писать вскользь, рекомендуется называть стандартно
  • термины: по какому полю группировать
  • поле: конкретное имя поля

Результат ответа следующий:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 5,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "song_qty_by_language": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "english",
          "doc_count": 5
        }
      ]
    }
  }
}

Объяснение синтаксиса:

  • hits: Так как при запросе установлено size: 0, хиты пустые
  • агрегации: агрегировать результаты запроса
  • song_qty_by_language: имя, объявленное при запросе
  • ведра: набор групп данных, полученных после запроса по указанному полю, в [] — каждая группа данных, где ключ — значение соответствующего указанного поля каждого ведра, а doc_count — количество статистики.

По умолчанию используется сортировка по doc_count в порядке убывания.

Средняя продолжительность каждой песни по языку

GET /music/children/_search
{
  "size": 0,
  "aggs": {
    "lang": {
      "terms": {
        "field": "language"
      },
      "aggs": {
        "length_avg": {
          "avg": {
            "field": "length"
          }
        }
      }
    }
  }
}

Здесь демонстрируется двухуровневый запрос агрегации ggs.Сначала подсчитывается статистика по языкам, чтобы получить группировку данных, а затем вычисляется средняя продолжительность в группировке данных.

То же самое верно и для синтаксиса вложенности нескольких ggs, обратите внимание на расположение блока кода ggs.

Подсчитайте песни с самыми длинными, самыми короткими и т. д.

Наиболее часто используемая статистика: count, avg, max, min, sum, смысл синтаксиса такой же, как у mysql.

GET /music/children/_search
{
  "size": 0,
  "aggs": {
    "color": {
      "terms": {
        "field": "language"
      },
      "aggs": {
        "length_avg": {
          "avg": {
            "field": "length"
          }
        },
        "length_max": {
          "max": {
            "field": "length"
          }
        },
        "length_min": {
          "min": {
            "field": "length"
          }
        },
        "length_sum": {
          "sum": {
            "field": "length"
          }
        }
      }
    }
  }
}

Статистика средней продолжительности песни по длительности

Возьмите 30 секунд в качестве сегмента и посмотрите среднее значение каждого интервала сегмента.

Синтаксическая позиция гистограммы такая же, как и у терминов, которая используется для разделения диапазона и используется вместе с параметром интервала. interval: 30 указывает, что сегмент интервала равен [0,30),[30,60),[60,90],[90,120)

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

GET /music/children/_search
{
  "size": 0,
  "aggs": {
    "sales_price_range": {
      "histogram": {
        "field": "length",
        "interval": 30
      },
      "aggs": {
        "length_avg": {
          "avg": {
            "field": "length"
          }
        }
      }
    }
  }
}

Результаты этих данных можно использовать для создания гистограммы или линейной диаграммы.

Дата добавления сегментирована путем подсчета количества новых песен

Статистика по месяцам

Гистограмма дат аналогична синтаксису гистограммы, с интервалом дат для указания интервала интервала. extended_bounds представляет максимальный диапазон времени.

GET /music/children/_search
{
  "size": 0,
  "aggs": {
    "sales": {
      "date_histogram": {
        "field": "releaseDate",
        "interval": "month",
        "format": "yyyy-MM-dd",
        "min_doc_count": 0,
        "extended_bounds": {
          "min": "2019-10-01",
          "max": "2019-12-31"
        }
      }
    }
  }
}

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

GET /music/children/_search
{
  "size": 0,
  "aggs": {
    "sales": {
      "date_histogram": {
        "field": "releaseDate",
        "interval": "quarter",
        "format": "yyyy-MM-dd",
        "min_doc_count": 0,
        "extended_bounds": {
          "min": "2019-01-01",
          "max": "2019-12-31"
        }
      },
      "aggs": {
        "lang_qty": {
          "terms": {
            "field": "language"
          },
          "aggs": {
            "like_sum": {
              "sum": {
                "field": "likes"
              }
            }
          }
        },
        "total" :{
          "sum": {
            "field": "likes"
          }
        }
      }
    }
  }
}

с фильтром

Агрегированный запрос можно использовать в сочетании с запросом, что эквивалентно комбинированному использованию where и group by в mysql.

Условия запроса
GET /music/children/_search
{
  "size": 0,
  "query": {
    "match": {
      "language": "english"
    }
  },
  "aggs": {
    "sales": {
      "terms": {
        "field": "language"
      }
    }
  }
}
фильтр
GET /music/children/_search
{
  "size": 0,
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "language": "english"
        }
      }
    }
  },
  "aggs": {
    "sales": {
      "terms": {
        "field": "language"
      }
    }
  }
}

глобальный запрос корзины

глобальный: это глобальное ведро, которое перенесет все данные в область агрегации и не будет затронуто предыдущим запросом или фильтром.

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

GET /music/children/_search
{
  "size": 0,
  "query": {
    "match": {
      "author": "Jean Ritchie"
    }
  },
  "aggs": {
    "likes": {
      "sum": {
        "field": "likes"
      }
    },
    "all": {
      "global": {},
      "aggs": {
        "all_likes": {
          "sum": {
            "field": "likes"
          }
        }
      }
    }
  }
}

Статистика количества лайков за последние два месяца и за последний месяц

aggs.filter для данных в агрегации

Фильтр ведра: фильтровать агги по разным ведрам

Подобно среде mysql, имеющей синтаксис

GET /music/children/_search
{
  "size": 0,
  "aggs": {
    "recent_60d": {
      "filter": {
        "range": {
          "releaseDate": {
            "gte": "now-60d"
          }
        }
      },
      "aggs": {
        "recent_60d_likes_sum": {
          "sum": {
            "field": "likes"
          }
        }
      }
    },
    "recent_30d": {
      "filter": {
        "range": {
          "releaseDate": {
            "gte": "now-30d"
          }
        }
      },
      "aggs": {
        "recent_30d_likes_sum": {
          "avg": {
            "field": "likes"
          }
        }
      }
    }
  }
}

Статистическая сортировка

По умолчанию сортируется в порядке убывания по doc_count.Правило сортировки можно изменить.Псевдоним aggs можно указывать по порядку, например length_avg, что аналогично порядку по cnt asc в mysql.

GET /music/children/_search
{
  "size": 0,
  "aggs": {
    "group_by_lang": {
      "terms": {
        "field": "language",
        "order": {
          "length_avg": "desc"
        }
      },
      "aggs": {
        "length_avg": {
          "avg": {
            "field": "length"
          }
        }
      }
    }
  }
}

резюме

В этой статье в основном представлены часто используемые запросы агрегации, все из которых основаны на примерах.После понимания основного метода написания вы можете быстро прочитать их.Если есть места, которые не легко понять, сравните их с SQL-запросом к базе данных, который мы знакомы с. Спасибо.

Сосредоточьтесь на Java с высоким параллелизмом и распределенной архитектуре, большем обмене техническими сухими товарами и опытом, пожалуйста, обратите внимание на общедоступный номер: Сообщество архитектуры Java Вы можете отсканировать QR-код слева, чтобы добавить друзей и пригласить вас присоединиться к группе WeChat сообщества архитектуры Java для совместного обсуждения технологий.

Java架构社区