благодарныйОбщийОбъяснение ElasticSearch, большинство из которых взято из этого
ElasticSearch
Сравнение MySQL и ElasticSearch
MySQL | ElasticSearch |
---|---|
База данных | Показатель |
Стол (стол) | Тип |
Ряд (ряд) | Документ |
Колонка (колонка) | Поле |
Схема | Отображение |
Показатель | Все индексируется по умолчанию (все поля индексируются) |
SQL (структурированный язык запросов) | Query DSL (специфический язык запросов) |
Document APIs
Index API
Index API позволяет нам хранить документ в формате JSON, что делает данные доступными для поиска. Документы однозначно идентифицируются по индексу, типу и идентификатору. id может предоставить идентификатор сам по себе или использовать Index API, чтобы сгенерировать его для нас.
Существует четыре различных способа создания документа (документа) в формате JSON.
- Ручной способ, используя собственный byte[] или String
- Используя метод Map, он будет автоматически преобразован в эквивалентный JSON.
- Используйте сторонние библиотеки для создания сериализованных bean-компонентов, например, JackJSON, FastJSON и т. д.
- Используйте встроенный вспомогательный класс XContentFactory.jsonBuilder().
Ручной способ
/**
* 手动方式
* @throws UnknownHostException
*/
@Test
public void JsonDocument() throws UnknownHostException {
String json = "{" +
"\"user\":\"deepredapple\"," +
"\"postDate\":\"2018-01-30\"," +
"\"message\":\"trying out Elasticsearch\"" +
"}";
IndexResponse indexResponse = client.prepareIndex("fendo", "fendodate").setSource(json).get();
System.out.println(indexResponse.getResult());
}
Метод карты
/**
* Map方式
*/
@Test
public void MapDocument() {
Map<String, Object> json = new HashMap<String, Object>();
json.put("user", "hhh");
json.put("postDate", "2018-06-28");
json.put("message", "trying out Elasticsearch");
IndexResponse response = client.prepareIndex(INDEX, TYPE).setSource(json).get();
System.out.println(response.getResult());
}
Метод сериализации
/**
* 使用JACKSON序列化
*/
@Test
public void JACKSONDocument() throws JsonProcessingException {
Blog blog = new Blog();
blog.setUser("123");
blog.setPostDate("2018-06-29");
blog.setMessage("try out ElasticSearch");
ObjectMapper mapper = new ObjectMapper();
byte[] bytes = mapper.writeValueAsBytes(blog);
IndexResponse response = client.prepareIndex(INDEX, TYPE).setSource(bytes).get();
System.out.println(response.getResult());
}
Вспомогательный класс XContentBuilder
/**
* 使用XContentBuilder帮助类方式
*/
@Test
public void XContentBuilderDocument() throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
.field("user", "xcontentdocument")
.field("postDate", "2018-06-30")
.field("message", "this is ElasticSearch").endObject();
IndexResponse response = client.prepareIndex(INDEX, TYPE).setSource(builder).get();
System.out.println(response.getResult());
}
Комплексный пример
package com.deepredapple.es.document;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author DeepRedApple
*/
public class TestClient {
TransportClient client = null;
public static final String INDEX = "fendo";
public static final String TYPE = "fendodate";
@Before
public void beforeClient() throws UnknownHostException {
client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
}
/**
* 手动方式
* @throws UnknownHostException
*/
@Test
public void JsonDocument() throws UnknownHostException {
String json = "{" +
"\"user\":\"deepredapple\"," +
"\"postDate\":\"2018-01-30\"," +
"\"message\":\"trying out Elasticsearch\"" +
"}";
IndexResponse indexResponse = client.prepareIndex(INDEX, TYPE).setSource(json).get();
System.out.println(indexResponse.getResult());
}
/**
* Map方式
*/
@Test
public void MapDocument() {
Map<String, Object> json = new HashMap<String, Object>();
json.put("user", "hhh");
json.put("postDate", "2018-06-28");
json.put("message", "trying out Elasticsearch");
IndexResponse response = client.prepareIndex(INDEX, TYPE).setSource(json).get();
System.out.println(response.getResult());
}
/**
* 使用JACKSON序列化
*/
@Test
public void JACKSONDocument() throws JsonProcessingException {
Blog blog = new Blog();
blog.setUser("123");
blog.setPostDate("2018-06-29");
blog.setMessage("try out ElasticSearch");
ObjectMapper mapper = new ObjectMapper();
byte[] bytes = mapper.writeValueAsBytes(blog);
IndexResponse response = client.prepareIndex(INDEX, TYPE).setSource(bytes).get();
System.out.println(response.getResult());
}
/**
* 使用XContentBuilder帮助类方式
*/
@Test
public void XContentBuilderDocument() throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
.field("user", "xcontentdocument")
.field("postDate", "2018-06-30")
.field("message", "this is ElasticSearch").endObject();
IndexResponse response = client.prepareIndex(INDEX, TYPE).setSource(builder).get();
System.out.println(response.getResult());
}
}
Get API
get API может просматривать документы по идентификатору
GetResponse getResponse = client.prepareGet(INDEX, TYPE, "AWRJCXMhro3r8sDxIpir").get();
Параметры индекс, тип, _id
настроить поток
Для setOperationThreaded установлено значение true, чтобы выполнить эту операцию в другом потоке.
/**
* Get API
*/
@Test
public void testGetApi() {
GetResponse getResponse = client.prepareGet(INDEX, TYPE, "AWRJCXMhro3r8sDxIpir").setOperationThreaded(false).get();
Map<String, Object> map = getResponse.getSource();
Set<String> keySet = map.keySet();
for (String str : keySet) {
Object o = map.get(str);
System.out.println(o.toString());
}
}
Delete API
Удалить по ID:
DeleteResponse deleteResponse = client.prepareDelete(INDEX, TYPE, "AWRJCXMhro3r8sDxIpir").get();
Параметры: индекс, тип, _id
настроить поток
Для setOperationThreaded установлено значение true, чтобы выполнить эту операцию в другом потоке.
/**
* deleteAPI
*/
@Test
public void testDeleteAPI() {
GetResponse getResponse = client.prepareGet(INDEX, TYPE, "AWRJCXMhro3r8sDxIpir").setOperationThreaded(false).get();
System.out.println(getResponse.getSource());
DeleteResponse deleteResponse = client.prepareDelete(INDEX, TYPE, "AWRJCXMhro3r8sDxIpir").get();
System.out.println(deleteResponse.getResult());
}
Delete By Query API
Удалить по условию запроса
/**
* 通过查询条件删除
*/
@Test
public void deleteByQuery() {
BulkByScrollResponse response = DeleteByQueryAction.INSTANCE.newRequestBuilder(client)
.filter(QueryBuilders.matchQuery("user", "hhh")) //查询条件
.source(INDEX).get();//索引名
long deleted = response.getDeleted();//删除文档数量
System.out.println(deleted);
}
Описание параметра Параметры QueryBuilders.matchQuery("user", "hhh") — это поля и условия запроса, а параметр source(INDEX) — это имя индекса.
Асинхронный обратный вызов
Когда время выполнения удаления слишком велико, операция удаления может быть выполнена в режиме асинхронного обратного вызова, а результат выполнения может быть получен в обратном вызове.
/**
* 回调的方式执行删除 适合大数据量的删除操作
*/
@Test
public void DeleteByQueryAsync() {
for (int i = 1300; i < 3000; i++) {
DeleteByQueryAction.INSTANCE.newRequestBuilder(client)
.filter(QueryBuilders.matchQuery("user", "hhh " + i))
.source(INDEX)
.execute(new ActionListener<BulkByScrollResponse>() {
public void onResponse(BulkByScrollResponse response) {
long deleted = response.getDeleted();
System.out.println("删除的文档数量为= "+deleted);
}
public void onFailure(Exception e) {
System.out.println("Failure");
}
});
}
}
Когда программа останавливается, операция удаления по-прежнему выполняется в консоли ElasticSearch и выполняется асинхронно.
Метод обратного вызова слушателя - это метод выполнения
.execute(new ActionListener<BulkByScrollResponse>() { //回调方法
public void onResponse(BulkByScrollResponse response) {
long deleted = response.getDeleted();
System.out.println("删除的文档数量为= "+deleted);
}
public void onFailure(Exception e) {
System.out.println("Failure");
}
});
Update API
индекс обновления
Существует два основных способа выполнения операции обновления.
- Создайте UpdateRequest и отправьте его через клиент
- Используйте метод prepareUpdate().
использованиеUpdateRequest
/**
* 使用UpdateRequest进行更新
*/
@Test
public void testUpdateAPI() throws IOException, ExecutionException, InterruptedException {
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index(INDEX);
updateRequest.type(TYPE);
updateRequest.id("AWRFv-yAro3r8sDxIpib");
updateRequest.doc(jsonBuilder()
.startObject()
.field("user", "hhh")
.endObject());
client.update(updateRequest).get();
}
использовать подготовку обновления ()
/**
* 使用PrepareUpdate
*/
@Test
public void testUpdatePrepareUpdate() throws IOException {
client.prepareUpdate(INDEX, TYPE, "AWRFvA7k0udstXU4tl60")
.setScript(new Script("ctx._source.user = \"DeepRedApple\"")).get();
client.prepareUpdate(INDEX, TYPE, "AWRFvA7k0udstXU4tl60")
.setDoc(jsonBuilder()
.startObject()
.field("user", "DeepRedApple")
.endObject()).get();
}
Параметры разных версий метода setScript в клиенте. операция.
Update By Script
Обновление документов с помощью скриптов
/**
* 通过脚本更新
*/
@Test
public void testUpdateByScript() throws ExecutionException, InterruptedException {
UpdateRequest updateRequest = new UpdateRequest(INDEX, TYPE, "AWRFvLSTro3r8sDxIpia")
.script(new Script("ctx._source.user = \"LZH\""));
client.update(updateRequest).get();
}
Upsert
Обновите документ, обновите, если документ существует, вставьте, если он не существует
/**
* 更新文档 如果存在更新,否则插入
*/
@Test
public void testUpsert() throws IOException, ExecutionException, InterruptedException {
IndexRequest indexRequest = new IndexRequest(INDEX, TYPE, "AWRFvLSTro3r8sDxIp12")
.source(jsonBuilder()
.startObject()
.field("user", "hhh")
.field("postDate", "2018-02-14")
.field("message", "ElasticSearch")
.endObject());
UpdateRequest updateRequest = new UpdateRequest(INDEX, TYPE, "AWRFvLSTro3r8sDxIp12")
.doc(jsonBuilder()
.startObject()
.field("user", "LZH")
.endObject())
.upsert(indexRequest); //如果不存在,就增加indexRequest
client.update(updateRequest).get();
}
Если _id в параметре существует, то есть индекс/тип/_id существует, то будет выполнен UpdateRequest, а если индекс/тип/_id не существует, он будет вставлен напрямую
Multi Get API
Получение нескольких документов одновременно,
/**
* 一次获取多个文档
*/
@Test
public void TestMultiGetApi() {
MultiGetResponse responses = client.prepareMultiGet()
.add(INDEX, TYPE, "AWRFv-yAro3r8sDxIpib") //一个ID的方式
.add(INDEX, TYPE, "AWRFvA7k0udstXU4tl60", "AWRJA72Uro3r8sDxIpip")//多个ID的方式
.add("blog", "blog", "AWG9GKCwhg1e21lmGSLH") //从另一个索引里面获取
.get();
for (MultiGetItemResponse itemResponse : responses) {
GetResponse response = itemResponse.getResponse();
if (response.isExists()) {
String source = response.getSourceAsString(); //_source
JSONObject jsonObject = JSON.parseObject(source);
Set<String> sets = jsonObject.keySet();
for (String str : sets) {
System.out.println("key -> " + str);
System.out.println("value -> "+jsonObject.get(str));
System.out.println("===============");
}
}
}
}
Bulk API
Buli API может реализовать пакетную вставку
/**
* 批量插入
*/
@Test
public void testBulkApi() throws IOException {
BulkRequestBuilder requestBuilder = client.prepareBulk();
requestBuilder.add(client.prepareIndex(INDEX, TYPE, "1")
.setSource(jsonBuilder()
.startObject()
.field("user", "张三")
.field("postDate", "2018-05-01")
.field("message", "zhangSan message")
.endObject()));
requestBuilder.add(client.prepareIndex(INDEX, TYPE, "2")
.setSource(jsonBuilder()
.startObject()
.field("user", "李四")
.field("postDate", "2016-09-10")
.field("message", "Lisi message")
.endObject()));
BulkResponse bulkResponse = requestBuilder.get();
if (bulkResponse.hasFailures()) {
System.out.println("error");
}
}
Useing Bulk Processor
Используя Bulk Processor, Bulk Processor предоставляет простой интерфейс для синхронизации пакетов автоматических запросов по номеру заданного размера.
Создание экземпляра массового процессора
Сначала создайте экземпляр Bulk Processor
/**
* 创建Processor实例
*/
@Test
public void testCreateBulkProcessor() {
BulkProcessor bulkProcessor = BulkProcessor.builder(client, new BulkProcessor.Listener() {
//调用Bulk之前执行,例如可以通过request.numberOfActions()方法知道numberOfActions
public void beforeBulk(long l, BulkRequest request) {
}
//调用Bulk之后执行,例如可以通过response.hasFailures()方法知道是否执行失败
public void afterBulk(long l, BulkRequest request, BulkResponse response) {
}
//调用失败抛出throwable
public void afterBulk(long l, BulkRequest bulkRequest, Throwable throwable) {
}
}).setBulkActions(10000) //每次10000个请求
.setBulkSize(new ByteSizeValue(5, ByteSizeUnit.MB)) //拆成5MB一块
.setFlushInterval(TimeValue.timeValueSeconds(5))//无论请求数量多少,每5秒钟请求一次
.setConcurrentRequests(1)//设置并发请求的数量。值为0意味着只允许执行一个请求。值为1意味着允许1并发请求
.setBackoffPolicy(
BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(100), 3))
//设置自定义重复请求机制,最开始等待100毫秒,之后成倍增加,重试3次,当一次或者多次重复请求失败后因为计算资源不够抛出EsRejectedExecutionException
// 异常,可以通过BackoffPolicy.noBackoff()方法关闭重试机制
.build();
}
Стандартный дизайн BulkProcess
- bulkActions 1000
- bulkSize 5mb
- не устанавливайте flushInterval
- concurrentRequests равно 1, асинхронное выполнение
- backoffPolicy повторяет 8 попыток, подождите 50 мс
/**
* 创建Processor实例
*/
@Test
public void testCreateBulkProcessor() throws IOException {
BulkProcessor bulkProcessor = BulkProcessor.builder(client, new BulkProcessor.Listener() {
//调用Bulk之前执行,例如可以通过request.numberOfActions()方法知道numberOfActions
public void beforeBulk(long l, BulkRequest request) {
}
//调用Bulk之后执行,例如可以通过response.hasFailures()方法知道是否执行失败
public void afterBulk(long l, BulkRequest request, BulkResponse response) {
}
//调用失败抛出throwable
public void afterBulk(long l, BulkRequest bulkRequest, Throwable throwable) {
}
}).setBulkActions(10000) //每次10000个请求
.setBulkSize(new ByteSizeValue(5, ByteSizeUnit.MB)) //拆成5MB一块
.setFlushInterval(TimeValue.timeValueSeconds(5))//无论请求数量多少,每5秒钟请求一次
.setConcurrentRequests(1)//设置并发请求的数量。值为0意味着只允许执行一个请求。值为1意味着允许1并发请求
.setBackoffPolicy(
BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(100), 3))
//设置自定义重复请求机制,最开始等待100毫秒,之后成倍增加,重试3次,当一次或者多次重复请求失败后因为计算资源不够抛出EsRejectedExecutionException
// 异常,可以通过BackoffPolicy.noBackoff()方法关闭重试机制
.build();
//增加requests
bulkProcessor.add(new IndexRequest(INDEX, TYPE, "3").source(
jsonBuilder()
.startObject()
.field("user", "王五")
.field("postDate", "2019-10-05")
.field("message", "wangwu message")
.endObject()));
bulkProcessor.add(new DeleteRequest(INDEX, TYPE, "1"));
bulkProcessor.flush();
//关闭bulkProcessor
bulkProcessor.close();
client.admin().indices().prepareRefresh().get();
client.prepareSearch().get();
}
Search API
API поиска может поддерживать поисковые запросы и возвращать результаты, соответствующие запросу. Он может выполнять поиск по одному индексу/типу или нескольким индексам/типам, и вы можете использовать Query Java API в качестве условий запроса.
Java предоставляет два типа поиска, QUERY_AND_FETCH и DFS_QUERY_AND_FETCH по умолчанию, но этот режим должен выбираться системой, а не указываться пользователем вручную.
Пример
@Test
public void testSearchApi() {
SearchResponse response = client.prepareSearch(INDEX).setTypes(TYPE)
.setQuery(QueryBuilders.matchQuery("user", "hhh")).get();
SearchHit[] hits = response.getHits().getHits();
for (int i = 0; i < hits.length; i++) {
String json = hits[i].getSourceAsString();
JSONObject object = JSON.parseObject(json);
Set<String> strings = object.keySet();
for (String str : strings) {
System.out.println(object.get(str));
}
}
}
Using scrolls in Java
Общие поисковые запросы всегда возвращают страницу данных, независимо от того, насколько большой объем данных будет возвращен пользователю, Scrolls API позволяет нам получить большой объем данных (даже все данные). API прокрутки позволяет нам создать первоначальную страницу поиска и непрерывно получать результаты из ElasticSearch в пакетном режиме до тех пор, пока не останется результатов. Scroll API был создан не для ответа пользователя в реальном времени, а для обработки больших объемов данных.
/**
* 滚动查询
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void testScrollApi() throws ExecutionException, InterruptedException {
MatchQueryBuilder qb = matchQuery("user", "hhh");
SearchResponse response = client.prepareSearch(INDEX).addSort(FieldSortBuilder.DOC_FIELD_NAME,
SortOrder.ASC)
.setScroll(new TimeValue(60000)) //为了使用scroll,初始搜索请求应该在查询中指定scroll参数,告诉ElasticSearch需要保持搜索的上下文环境多长时间
.setQuery(qb)
.setSize(100).get();
do {
for (SearchHit hit : response.getHits().getHits()) {
String json = hit.getSourceAsString();
JSONObject object = JSON.parseObject(json);
Set<String> strings = object.keySet();
for (String str : strings) {
System.out.println(object.get(str));
}
}
response = client.prepareSearchScroll(response.getScrollId()).setScroll(new TimeValue(60000)).execute().get();
} while (response.getHits().getHits().length != 0);
}
Если время прокрутки превышено, а идентификатор прокрутки продолжает использоваться для поиска данных, будет сообщено об ошибке.
Хотя время прокрутки истекло, контекст поиска будет автоматически очищен, но постоянная прокрутка обойдется дорого, поэтому мы должны использовать Clear-Scroll API, чтобы очистить его как можно скорее, когда мы не используем прокрутку.
очистить идентификатор прокрутки
ClearScrollRequestBuilder clearBuilder = client.prepareClearScroll();
clearBuilder.addScrollId(response.getScrollId());
ClearScrollResponse scrollResponse = clearBuilder.get();
System.out.println("是否清楚成功:"+scrollResponse.isSucceeded());
MultiSearch API
MultiSearch API позволяет выполнять несколько поисковых запросов в одном и том же API. Его конечная точка — _msearch.
@Test
public void testMultiSearchApi() {
SearchRequestBuilder srb1 = client.prepareSearch().setQuery(QueryBuilders.queryStringQuery("elasticsearch")).setSize(1);
SearchRequestBuilder srb2 = client.prepareSearch().setQuery(QueryBuilders.matchQuery("user", "hhh")).setSize(1);
MultiSearchResponse multiSearchResponse = client.prepareMultiSearch().add(srb1).add(srb2).get();
long nbHits = 0;
for (MultiSearchResponse.Item item : multiSearchResponse.getResponses()) {
SearchResponse response = item.getResponse();
nbHits += response.getHits().getTotalHits();
}
System.out.println(nbHits);
}
Using Aggregations
Платформы агрегации помогают предоставлять данные на основе поисковых запросов. Он основан на простых строительных блоках, также известных как интеграция, которая представляет собой упорядоченное объединение сложных сводок данных. Агрегацию можно рассматривать как общий термин для серии заданий, которые получают аналитическую информацию из набора документов. Процесс реализации агрегации — это процесс определения этого набора документов.
@Test
public void testAggregations() {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(QueryBuilders.matchAllQuery())
.addAggregation(AggregationBuilders.terms("LZH").field("user"))
.addAggregation(AggregationBuilders.dateHistogram("2013-01-30").field("postDate")
.dateHistogramInterval(DateHistogramInterval.YEAR)).get();
Terms lzh = searchResponse.getAggregations().get("user");
Histogram postDate = searchResponse.getAggregations().get("2013-01-30");
}
Terminate After
Получить максимальное количество документов. Если установлено, вам нужно использовать isTerminatedEarly() в объекте SearchResponse, чтобы определить, достигают ли возвращенные документы установленного количества
@Test
public void TestTerminate() {
SearchResponse searchResponse = client.prepareSearch(INDEX)
.setTerminateAfter(2) //如果达到这个数量,提前终止
.get();
if (searchResponse.isTerminatedEarly()) {
System.out.println(searchResponse.getHits().totalHits);
}
}
Aggregations
полимеризация. ElasticSearch предоставляет полный API Java для работы с агрегатами. Используйте AggregationBuilders для создания объектов для добавления в поисковые запросы.
SearchResponse response = client.prepareSearch().setQuery(/*查询*/).addAggregation(/*聚合*/).execute().actionGet();
Structuring aggregations
Структурированная агрегация.
Metrics aggregations
Такие операции агрегирования в классе Computed Metric основаны на использовании метода или извлечении значений для агрегирования из документа.
Основными классами, используемыми при этом, являются **
AggregationBuilders
**, который содержит большое количество вызовов методов агрегации, которые можно использовать напрямую
Мин. агрегация
MinAggregationBuilder aggregation = AggregationBuilders.min("agg").field("age");
SearchResponse sr = client.prepareSearch("twitter").addAggregation(aggregation).get();
Min agg = sr.getAggregations().get("agg");
String value = agg.getValueAsString();//这个统计的是日期,一般用下面方法获得最小值
System.out.println("min value:" + value);
в режиме отладки
Первая строка toString() MinAggregationBuilder выполняется следующим образом.
{
"error": "JsonGenerationException[Can not write a field name, expecting a value]"
}
SearchResponse sr = client.prepareSearch("twitter").addAggregation(aggregation).get();
Содержимое toString() в SearchResponse выглядит следующим образом. Это содержимое представляет собой результат запроса в формате JSON. Структура результата JSON сопоставляется с операцией API SearchResponse для получения каждого значения в нем.
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 1.0,
"hits": [
{
"_index": "twitter",
"_type": "tweet",
"_id": "10",
"_score": 1.0,
"_source": {
"user": "kimchy",
"postDate": "2018-06-29T09:10:21.396Z",
"age": 30,
"gender": "female",
"message": "trying out Elasticsearch"
}
},
{
"_index": "twitter",
"_type": "tweet",
"_id": "2",
"_score": 1.0,
"_source": {
"user": "kimchy",
"postDate": "2018-06-29T09:05:33.943Z",
"age": 20,
"gender": "female",
"message": "trying out Elasticsearch"
}
},
{
"_index": "twitter",
"_type": "tweet",
"_id": "1",
"_score": 1.0,
"_source": {
"user": "kimchy",
"postDate": "2018-06-29T08:59:00.191Z",
"age": 10,
"gender": "male",
"message": "trying out Elasticsearch"
}
},
{
"_index": "twitter",
"_type": "tweet",
"_id": "11",
"_score": 1.0,
"_source": {
"user": "kimchy",
"postDate": "2018-06-29T09:10:54.386Z",
"age": 30,
"gender": "female",
"message": "trying out Elasticsearch"
}
}
]
},
"aggregations": {
"agg": {
"value": 10.0
}
}
}
Его можно найти путем наблюденияsr.getAggregations().get("agg");
Метод заключается в получении данных агрегированной статистики, а параметр agg во всем коде можно настроить
Максимальная агрегация
MaxAggregationBuilder aggregation = AggregationBuilders.max("agg").field("readSize");
SearchResponse sr = client.prepareSearch("blog").addAggregation(aggregation).get();
Max agg = sr.getAggregations().get("agg");
String value = agg.getValueAsString();
System.out.println("max value:" + value);
Конкретный метод анализа такой же, как и агрегация Min Aggregation,Но невозможно подсчитать максимальные и минимальные значения каких данных
Суммарное агрегирование
SumAggregationBuilder aggregation = AggregationBuilders.sum("agg").field("readSize");
SearchResponse sr = client.prepareSearch("blog").addAggregation(aggregation).get();
Sum agg = sr.getAggregations().get("agg");
String value = agg.getValueAsString();
System.out.println("sum value:" + value);
Среднее агрегирование Среднее агрегирование
AvgAggregationBuilder aggregation = AggregationBuilders.avg("agg").field("age");
SearchResponse searchResponse = client.prepareSearch("twitter").addAggregation(aggregation).get();
Avg avg = searchResponse.getAggregations().get("agg");
String value = avg.getValueAsString();
System.out.println("avg value: "+ value);
Статистическая сводка Статистическая сводка
Статистическая агрегация - расчет некоторой статистической информации (минимум, максимум, сумма, количество, среднее) на основе определенного значения документа. Значение, используемое для расчета, может быть определенным числовым полем или может быть рассчитано с помощью скрипта.
StatsAggregationBuilder aggregation = AggregationBuilders.stats("agg").field("age");
SearchResponse searchResponse = client.prepareSearch("twitter").addAggregation(aggregation).get();
Stats stats = searchResponse.getAggregations().get("agg");
String max = stats.getMaxAsString();
String min = stats.getMinAsString();
String avg = stats.getAvgAsString();
String sum = stats.getSumAsString();
long count = stats.getCount();
System.out.println("max value: "+max);
System.out.println("min value: "+min);
System.out.println("avg value: "+avg);
System.out.println("sum value: "+sum);
System.out.println("count value: "+count);
Эта агрегированная статистика может подсчитывать обычные статистические значения выше. Этот метод можно использовать, когда необходимо подсчитать большинство из вышеперечисленных значений.
Агрегация расширенной статистики Агрегация расширенной статистики
Расширенная статистическая агрегация - на основе определенного значения документа вычислить некоторую статистическую информацию (больше sum_of_squares, variance, std_deviation, std_deviation_bounds, чем обычная статистическая агрегация), значение, используемое для расчета, может быть определенным числовым полем или может быть передано через сценарий просчитан. Основным значением результата является статистическое значение максимума, минимума, дисперсии, квадрата разности и т.д.
ExtendedStatsAggregationBuilder aggregation = AggregationBuilders.extendedStats("agg").field("age");
SearchResponse response = client.prepareSearch("twitter").addAggregation(aggregation).get();
ExtendedStats extended = response.getAggregations().get("agg");
String max = extended.getMaxAsString();
String min = extended.getMinAsString();
String avg = extended.getAvgAsString();
String sum = extended.getSumAsString();
long count = extended.getCount();
double stdDeviation = extended.getStdDeviation();
double sumOfSquares = extended.getSumOfSquares();
double variance = extended.getVariance();
System.out.println("max value: " +max);
System.out.println("min value: " +min);
System.out.println("avg value: " +avg);
System.out.println("sum value: " +sum);
System.out.println("count value: " +count);
System.out.println("stdDeviation value: " +stdDeviation);
System.out.println("sumOfSquares value: " +sumOfSquares);
System.out.println("variance value: "+variance);
Агрегация количества значений
Агрегирование подсчета значений — подсчитайте количество значений в агрегированном документе, значение, используемое для расчета, может быть определенным числовым полем или может быть рассчитано с помощью сценария. Эта агрегация обычно используется в сочетании с другими агрегациями с одним значением.Например, при расчете среднего значения поля вы также можете обратить внимание на то, из скольких значений рассчитывается среднее значение.
ValueCountAggregationBuilder aggregation = AggregationBuilders.count("agg").field("age");
SearchResponse response = client.prepareSearch("twitter").addAggregation(aggregation).get();
ValueCount count = response.getAggregations().get("agg");
long value = count.getValue();
System.out.println("ValueCount value: " +value);
Прецентильная агрегация
PercentilesAggregationBuilder aggregation = AggregationBuilders.percentiles("agg").field("age");
SearchResponse response = client.prepareSearch("twitter").addAggregation(aggregation).get();
Percentiles agg = response.getAggregations().get("agg");
for (Percentile entry : agg) {
double percent = entry.getPercent();
double value = entry.getValue();
System.out.println("percent value: " + percent + "value value: " + value);
}
Агрегация количества элементов
Мощность для удаления дубликатов
CardinalityAggregationBuilder aggregation = AggregationBuilders.cardinality("agg").field("age");
SearchResponse response = client.prepareSearch("twitter").addAggregation(aggregation).get();
Cardinality agg = response.getAggregations().get("agg");
long value = agg.getValue();
System.out.println("value value: "+ value);
Агрегация лучших хитов
Запрос количества полей совпадающих документов
TermsAggregationBuilder aggregation = AggregationBuilders.terms("agg").field("gender.keyword")
.subAggregation(AggregationBuilders.topHits("top").explain(true).size(1).from(10));
SearchResponse response = client.prepareSearch("twitter").addAggregation(aggregation).get();
Terms agg = response.getAggregations().get("agg");
for (Terms.Bucket bucket : agg.getBuckets()) {
String key = (String) bucket.getKey();
long docCount = bucket.getDocCount();
System.out.println("key value: " + key + " docCount value: " + docCount);
TopHits topHits = bucket.getAggregations().get("top");
for (SearchHit searchHitFields : topHits.getHits().getHits()) {
System.out.println("id value: " + searchHitFields.getId() + " source value: " + searchHitFields.getSourceAsString());
}
}
Bucket aggregations
Глобальная агрегацияГлобальная агрегация
Запрос глобальной статистики
AggregationBuilder aggregation = AggregationBuilders
.global("agg")
.subAggregation(
AggregationBuilders.terms("users").field("user.keyword")
);
SearchResponse sr = client.prepareSearch("twitter")
.addAggregation(aggregation)
.get();
System.out.println(sr);
Global agg = sr.getAggregations().get("agg");
long count = agg.getDocCount(); // Doc count
System.out.println("global count:" + count);
Агрегация фильтров Агрегация фильтров
фильтровать статистику
AggregationBuilder aggregation = AggregationBuilders.filters("aaa", new FiltersAggregator.KeyedFilter("men", QueryBuilders.termQuery("gender", "male")));
SearchResponse sr = client.prepareSearch("twitter").setTypes("tweet").addAggregation(aggregation).get();
Filters agg = sr.getAggregations().get("aaa");
for (Filters.Bucket entry : agg.getBuckets()) {
String key = entry.getKeyAsString(); // bucket key
long docCount = entry.getDocCount(); // Doc count
System.out.println("global " + key + " count:" + docCount);
}
Агрегация фильтровАгрегация нескольких фильтров
Фильтр по нескольким условиям, запрос числа
AggregationBuilder aggregation = AggregationBuilders.filters("aaa",new FiltersAggregator.KeyedFilter("men", QueryBuilders.termQuery("gender", "male")),new FiltersAggregator.KeyedFilter("women", QueryBuilders.termQuery("gender", "female")));
SearchResponse sr = client.prepareSearch("twitter").setTypes("tweet").addAggregation(aggregation).get();
Filters agg = sr.getAggregations().get("aaa");
for (Filters.Bucket entry : agg.getBuckets()) {
String key = entry.getKeyAsString(); // bucket key
long docCount = entry.getDocCount(); // Doc count
System.out.println("global " + key + " count:" + docCount);
}
Отсутствует агрегирование. Агрегирование одного сегмента на основе полевых данных.
Агрегация вложенного типа Агрегация вложенного типа
Reverse nested Aggregation
Children Aggregation
Агрегация терминов Лексическая агрегация
TermsAggregationBuilder fieldAggregation = AggregationBuilders.terms("genders").field("gender.keyword")
.order(Terms.Order.term(true));
SearchResponse response = client.prepareSearch("twitter").setTypes("tweet").addAggregation(fieldAggregation).get();
Terms terms = response.getAggregations().get("genders");
for (Terms.Bucket bucket : terms.getBuckets()) {
System.out.println("key value: " + bucket.getKey());
System.out.println("docCount value: " + bucket.getDocCount());
}
Заказысортировать
TermsAggregationBuilder fieldAggregation = AggregationBuilders.terms("genders").field("gender.keyword")
.order(Terms.Order.term(true));
Significant Terms Aggregation
Агрегация диапазона
Агрегирование диапазона дат
Объединение диапазонов IP-адресов Объединение диапазонов IP-адресов
Агрегация гистограммы Агрегация гистограммы
Агрегирование гистограммы дат Диапазон дат Агрегирование гистограммы
Объединение географических расстояний
Агрегация сетки Geo Hash Агрегация сетки GeoHash
Query DSL
Match All Query
соответствовать всем документам
QueryBuilder qb = matchAllQuery();
Full text Query
сопоставить запрос
Нечеткое совпадение и запрос полевой фразы
QueryBuilder qb = matchQuery("gender", "female");
запрос multi_mathc запрос с несколькими полями
Несколько полей для запроса, поля могут иметь несколько
QueryBuilder qb = multiMatchQuery("female","gender", "message");
запрос common_terms запрос общих терминов
Делайте более профессиональные запросы по некоторым более профессиональным неполным словам
QueryBuilder qb = commonTermsQuery("gender","female");
query_string запрос запрос запрос запрос
Запрос в сочетании с синтаксисом запросов Lucene, который позволяет выполнять запросы с особыми условиями (И|ИЛИ|НЕ).
QueryBuilder qb = queryStringQuery("+male -female");
simple_string queryПростой оператор запроса
Простой синтаксис запроса
QueryBuilder qb = queryStringQuery("+male -female");
Term level Query
Запрос элемента Term Query
Запрос документа для точного значения в указанном поле
QueryBuilder qb = termQuery("gender","male");
Термины ЗапросНесколько запросов
Запрос нескольких точных значений в поле
QueryBuilder qb = termsQuery("age","10", "20");
Запрос диапазона запросов
запрос диапазона
- gte(): запросы диапазона будут соответствовать документам, значение поля которых больше или равно значению этого параметра.
- gt(): запросы диапазона будут соответствовать документам со значениями полей, превышающими значение этого параметра.
- lte(): запросы диапазона будут соответствовать документам, значение поля которых меньше или равно значению этого параметра.
- lt(): запросы диапазона будут соответствовать документам, значение поля которых меньше значения этого параметра.
- from() начальное значение to() результирующее значение, эти две функции используются в сочетании с функциями includeLower() и includeUpper().
- includeLower(true) означает, что запрос from() будет соответствовать документам, значение поля которых больше или равно значению этого параметра.
- includeLower(false) означает, что запрос from() будет соответствовать документам, значение поля которых больше, чем значение этого параметра.
- includeUpper(true) означает, что запрос to() будет соответствовать документам, значение поля которых меньше или равно значению этого параметра.
- includeUpper(false) означает, что запрос to() будет соответствовать документам, значение поля которых меньше значения этого параметра.
QueryBuilder qb = QueryBuilders.rangeQuery("age").gte(10).includeLower(true).lte(20).includeUpper(true);
Среди них методы includeLower() и includeUpper() указывают, содержит ли область запрос
Существует запрос существует запрос
Запрос, существует ли он на основе указанного имени поля
QueryBuilder qb = existsQuery("user");
Префиксный запрос Префиксный запрос
Запрос на основе указанного имени поля и указанного точного префикса
QueryBuilder qb = prefixQuery("gender","m");
Подстановочный запрос Подстановочный запрос
Запрос с подстановочными знаками, укажите имя поля и подстановочный знак. Где? представляет собой односимвольный подстановочный знак, а * представляет собой многосимвольный подстановочный знак. Все поля запроса с подстановочными знаками являются непроанализированными полями.
QueryBuilder qb = wildcardQuery("gender","f?*");
Запрос регулярного выражения Regexp Query
Запрос на основе указанного имени поля и регулярного выражения. Запрашиваемое поле также является неанализируемым полем
QueryBuilder qb = regexpQuery("gender","f.*");
Нечеткий запрос
Нечеткий запрос: укажите точное имя поля и содержание запроса с ошибками
QueryBuilder qb = fuzzyQuery("gender","mala").fuzziness(Fuzziness.ONE);
Тип запроса Тип запроса
Запросить документ указанного типа
QueryBuilder qb = typeQuery("tweet");
Идентификатор запроса идентификатора запроса
В соответствии с типом типа и запросом идентификатора тип типа не может быть записан
QueryBuilder qb = idsQuery("tweet").addIds("1", "11");