Elasticsearch Java API 6.0

本贴最后更新于 2322 天前,其中的信息可能已经水流花落

官方地址: https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html

版本: Elasticsearch 6.0

Client

你可以通过多种方式来使用 Java client

  • 在一个存在的集群上执行一个标准的 index,get,delete 和 search 操作
  • 在一个正在运行的集群上执行管理任何

获取一个 elasticsearch 客户端是一件容易的事情.通常最常用的方式是创建一个 TransportClient 来连接一个集群.

客户端的主版本(比如 2.x 或 5.x)必须要与节点保持一致.客户端可以连接多个拥有不同次版本的集群(比如 2.3.x),但是可能会有些功能不可用.理想的情况是,客户端与集群拥有相关的版本号.

如果是用来执行一个被 Java 请求序列化而来的 HTTP 请求 TransportClient 可能会被 Java High Level REST Client 所取代.在 Elasticsearch 未来的版本中,TransportClient 将不推荐被使用,你应该尽可能使用 Java High Level REST Client 来替换.

Document APIs

该部分讨论如下 CRUD APIs

Single document APIs

Multi-document APIs

所有的 CRUD APIs 都是单文档 APIs.索引模式支持单独的索引名称,也支持指向某个索引的别名

Index API

索引 API 允许向一个指定的索引中添加一个 JSON 类型的文档,并且让它能够被搜索到

Generate JSON document

下面有几种方式来生成一个 JSON 文档

  • 手动地(又被称为你自己来做)使用本地字节数组作为一个字符串

  • 使用一个 Map 转换成一个等价的 JSON

  • 使用第三方库,比如 jackson,来序列化你的 bean

  • 使用内置的辅助类,XContentFactory.jsonBuilder()

内部地,每种类型都会转换成字节数组(字符串也会被转换成字节数组).因此,如果对象已经在一个表单中,请使用它.jsonBuilder 是通过构造器(从字节数组中)生成 json 的最佳方式.

1. 自己生成

这里没有什么特别困难的,但是要注意,您必须按照日期格式编码日期.

String json = "{" +
        "\"user\":\"kimchy\"," +
        "\"postDate\":\"2013-01-30\"," +
        "\"message\":\"trying out Elasticsearch\"" +
    "}";

2. 使用 map

map 是一个键值对的集合.同时也代表一个 JSON 格式

Map json = new HashMap();
json.put("user","kimchy");
json.put("postDate",new Date());
json.put("message","trying out Elasticsearch");

3. 序列化你的 beans

你可以使用 jackson 来将你的 bean 序列化成 JSON.请在你的项目中添加"Jackson Databind",然后你可以使用 ObjectMapper 来序列化你的 beans

import com.fasterxml.jackson.databind.*;

// instance a json mapper
ObjectMapper mapper = new ObjectMapper(); // create once, reuse

// generate json
byte[] json = mapper.writeValueAsBytes(yourbeaninstance);

4. 使用 Elasticsearch 工具类

Elasticsearch 提供了一个内置的辅助类来生成 JSON 内容

import static org.elasticsearch.common.xcontent.XContentFactory.*;

XContentBuilder builder = jsonBuilder()
    .startObject()
        .field("user", "kimchy")
        .field("postDate", new Date())
        .field("message", "trying out Elasticsearch")
    .endObject()

需要注意的是,你可以同样使用 startArray(String)和 endArray()方法来生成一个 json 数组.顺便说一下,field 方法接受多种对象类型.你能够直接使用数字类型,日期类型,甚至是 XContentBuilder 对象.

如果你需要生成 json 内容,你需要调用 string()方法

String json = builder.string();

index document

如下的例子,索引一个 JSON 文档到一个类型为"tweet",索引名称为"twitter"的索引中,并且它的值为 1

import static org.elasticsearch.common.xcontent.XContentFactory.*;

IndexResponse response = client.prepareIndex("twitter", "tweet", "1")
        .setSource(jsonBuilder()
                    .startObject()
                        .field("user", "kimchy")
                        .field("postDate", new Date())
                        .field("message", "trying out Elasticsearch")
                    .endObject()
                  )
        .get();

请注意,你同样可以在不给定 ID 且为 JSON 字符串的的情况下索引一个文档到索引中.

String json = "{" +
        "\"user\":\"kimchy\"," +
        "\"postDate\":\"2013-01-30\"," +
        "\"message\":\"trying out Elasticsearch\"" +
    "}";

IndexResponse response = client.prepareIndex("twitter", "tweet")
        .setSource(json, XContentType.JSON)
        .get();

IndexResponse 对象将会给你返回结果的一个报告

// Index name
String _index = response.getIndex();
// Type name
String _type = response.getType();
// Document ID (generated or not)
String _id = response.getId();
// Version (if it's the first time you index this document, you will get: 1)
long _version = response.getVersion();
// status has stored current instance statement.
RestStatus status = response.status();

如果想了解更多关于索引操作的信息,请检查 Rest index 文档.

Operation Threading

文档索引 API 允许设置线程模型,当在相同节点上执行 API 的实际执行时执行操作(该 API 在分配在同一服务器上的分片上执行)的时候,这个操作将会被执行。
选项是在不同的线程上执行操作,或者在调用线程上执行它(注意,API 仍然是异步的)。 默认情况下,operationThreaded 设置为 true,这意味着操作在不同的线程上执行.

Get API

索引获取 api 允许根据一个文档 ID 来获取一个 JSON 类型的文档.下面的例子将会从一个索引名称为"twitter",类型名称为"tweet",id 为 1 的索引中获取一个 json 文档

GetResponse response = client.prepareGet("twitter", "tweet", "1").get();

Operation Threading

文档获取 API 允许设置线程模型,当在相同节点上执行 API 的实际执行时执行操作(该 API 在分配在同一服务器上的分片上执行)的时候,这个操作将会被执行。
选项是在不同的线程上执行操作,或者在调用线程上执行它(注意,API 仍然是异步的)。 默认情况下,operationThreaded 设置为 true,这意味着操作在不同的线程上执行.下面的例子设置该值为 false

GetResponse response = client.prepareGet("twitter", "tweet", "1")
        .setOperationThreaded(false)
        .get();

Delete API

文档删除 api 允许根据一个文档 ID 来删除一个 JSON 类型的文档.下面的例子将会从一个索引名称为"twitter",类型名称为"tweet",id 为 1 的索引中删除一个 json 文档

DeleteResponse response = client.prepareDelete("twitter", "tweet", "1").get();

想了解更多关于删除操作的信息,请打开 delete api 文档.

Operation Threading

文档删除 API 允许设置线程模型,当在相同节点上执行 API 的实际执行时执行操作(该 API 在分配在同一服务器上的分片上执行)的时候,这个操作将会被执行。
选项是在不同的线程上执行操作,或者在调用线程上执行它(注意,API 仍然是异步的)。 默认情况下,operationThreaded 设置为 true,这意味着操作在不同的线程上执行.下面的例子设置该值为 false

DeleteResponse response = client.prepareDelete("twitter", "tweet", "1")
        .setOperationThreaded(false)
        .get();

Delete By Query API

通过查询来删除文档 API 允许根据一个或读个查询条件来删除索引中的文档:

BulkByScrollResponse response =
    DeleteByQueryAction.INSTANCE.newRequestBuilder(client)
        .filter(QueryBuilders.matchQuery("gender", "male")) 1
        .source("persons")                2
        .get();              3                              
long deleted = response.getDeleted();   4                  
  1. 查询
  2. 索引
  3. 执行操作
  4. 删除文档的数量

该删除操作可能会运行很长时间,如果你希望它异步来执行,你可以调用 execute 方法来替代 get 方法,并且提供一个监听器来监听该操作,如

DeleteByQueryAction.INSTANCE.newRequestBuilder(client)
    .filter(QueryBuilders.matchQuery("gender", "male"))       1  
    .source("persons")                   2                                
    .execute(new ActionListener() {           3
        @Override
        public void onResponse(BulkByScrollResponse response) {
            long deleted = response.getDeleted();        4                
        }
        @Override
        public void onFailure(Exception e) {
            // Handle the exception
        }
    });
  1. 查询
  2. 索引
  3. 监听
  4. 删除文档数量

Update API

你可以使用 client 来创建一个 UpdateRequest 请求来发送给集群

UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index("index");
updateRequest.type("type");
updateRequest.id("1");
updateRequest.doc(jsonBuilder()
        .startObject()
            .field("gender", "male")
        .endObject());
client.update(updateRequest).get();

或者你可以调用 prepareUpdate()方法

client.prepareUpdate("ttl", "doc", "1")
        .setScript(new Script("ctx._source.gender = \"male\"" ,  1
	ScriptService.ScriptType.INLINE, null, null))
        .get();

client.prepareUpdate("ttl", "doc", "1")
        .setDoc(jsonBuilder()              2
            .startObject()
                .field("gender", "male")
            .endObject())
        .get();
  1. 你的脚本.它也可以是一个本地存储的脚本文件名称,当然你需要使用 ScriptService.ScriptType.FILE.

  2. 该文档会与存在的原文档进行合并操作

请注意,你不能同时使用 script 和 doc.

Update by script

更新 API 能够允许通过提供一个脚本来更新文档

UpdateRequest updateRequest = new UpdateRequest("ttl", "doc", "1")
        .script(new Script("ctx._source.gender = \"male\""));
client.update(updateRequest).get();

Update by merging documents

文档更新 API 同样支持通过提供一个局部文档来与原文档进行合并(简单的进行递归合并,对象内部合并,替换核心的"key/value"以及数组),例如:

UpdateRequest updateRequest = new UpdateRequest("index", "type", "1")
        .doc(jsonBuilder()
            .startObject()
                .field("gender", "male")
            .endObject());
client.update(updateRequest).get();

Upsert

文档更新 API 也同样支持更新插入操作.如果文档不存在则执行插入操作,如果文档存在则执行更新操作

IndexRequest indexRequest = new IndexRequest("index", "type", "1")
        .source(jsonBuilder()
            .startObject()
                .field("name", "Joe Smith")
                .field("gender", "male")
            .endObject());
UpdateRequest updateRequest = new UpdateRequest("index", "type", "1")
        .doc(jsonBuilder()
            .startObject()
                .field("gender", "male")
            .endObject())
        .upsert(indexRequest);            1
client.update(updateRequest).get();
  1. 如果文档不存在,则会添加 indexRequest 请求.

如果文档 index/type/1 已经存在,我们将会执行一个更新操作并获取如下的文档

{
    "name"  : "Joe Dalton",
    "gender": "male"        1
}
  1. 该字段是通过 update 请求来添加的

如果该文档不存在,我们将获取一个新文档

{
    "name" : "Joe Smith",
    "gender": "male"
}

Multi Get API

多文档获取 API 允许基于文档的 index,type 和 id 来获取一个文档列表

MultiGetResponse multiGetItemResponses = client.prepareMultiGet()
    .add("twitter", "tweet", "1")          1
    .add("twitter", "tweet", "2", "3", "4") 2
    .add("another", "type", "foo")          3
    .get();

for (MultiGetItemResponse itemResponse : multiGetItemResponses) { 4
    GetResponse response = itemResponse.getResponse();
    if (response.isExists()) {                     5
        String json = response.getSourceAsString(); 6
    }
}
  1. 通过一个单独的 id 获取文档
  2. 通过一个列表式的文档 id 集合来获取相同索引/类型下的文档列表
  3. 也可以获取其他索引下的文档
  4. 遍历结果集
  5. 检查文档是否存在
  6. 获取文档的_source 字段

如果想了解更多关于多文档获取 API 的信息,请参考:multi get

Bulk API

批量操作 API 允许我们通过一个单路的请求来同时执行一系列的索引或删除操作.如下例:

import static org.elasticsearch.common.xcontent.XContentFactory.*;

BulkRequestBuilder bulkRequest = client.prepareBulk();

// either use client#prepare, or use Requests# to directly build index/delete requests
bulkRequest.add(client.prepareIndex("twitter", "tweet", "1")
        .setSource(jsonBuilder()
                    .startObject()
                        .field("user", "kimchy")
                        .field("postDate", new Date())
                        .field("message", "trying out Elasticsearch")
                    .endObject()
                  )
        );

bulkRequest.add(client.prepareIndex("twitter", "tweet", "2")
        .setSource(jsonBuilder()
                    .startObject()
                        .field("user", "kimchy")
                        .field("postDate", new Date())
                        .field("message", "another post")
                    .endObject()
                  )
        );

BulkResponse bulkResponse = bulkRequest.get();
if (bulkResponse.hasFailures()) {
    // process failures by iterating through each bulk response item
}

Using Bulk Processor

BulkProcessor 类提供一个简单的接口用来自动刷新批量操作,前提是基于请求数量或给定一个周期

为了使用它,首选需要创建一个 BulkProcessor 实例

import org.elasticsearch.action.bulk.BackoffPolicy;
import org.elasticsearch.action.bulk.BulkProcessor;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;

BulkProcessor bulkProcessor = BulkProcessor.builder(
        client,   1
        new BulkProcessor.Listener() {
            @Override
            public void beforeBulk(long executionId,
                                   BulkRequest request) { ... }  2

            @Override
            public void afterBulk(long executionId,
                                  BulkRequest request,
                                  BulkResponse response) { ... } 3

            @Override
            public void afterBulk(long executionId,
                                  BulkRequest request,
                                  Throwable failure) { ... } 4
        })
        .setBulkActions(10000) 5
        .setBulkSize(new ByteSizeValue(5, ByteSizeUnit.MB)) 6
        .setFlushInterval(TimeValue.timeValueSeconds(5)) 7
        .setConcurrentRequests(1) 8
        .setBackoffPolicy(
            BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(100), 3)) 9
        .build();
  1. 添加你的 elasticsearch 客户端
  2. 在 bulk 方法执行之前调用,你可以在这里通过 request.numberOfActions()方法知道执行的操作数量
  3. 在 bulk 方法执行之后调用,你可以通过 response.hasFailures()方法知道哪些失败的请求
  4. 如果 bulk 执行失败或抛出一个异常则会调用该方法
  5. 我们想每个 bulk 操作执行 10000 个请求
  6. 我们想每次占用 5Mb 内存的时候刷新 bulk 操作
  7. 我们想每隔 5S 中刷新内存而忽略请求次数
  8. 设置并发请求的数量.如果设置为 0 则意味着只允许执行一个 bulk 请求,如果设置为 1,则在执行当前 bulk 请的时候允许执行其他 bulk 请求.
  9. 设置一个自定义的补偿策略,它最初将等待 100ms,以指数级增长,并重新尝试三次。当一个或多个 bulk 请求操作失败时都会伴随着一次请求重试且抛出 EsRejectedExecutionException,这表明有太少的计算资源用于处理请求。如果想禁用 backoff,通过 backoffpolicy . nobackoff()设置来完成.

默认情况,BulkProcessor 设置如下:

  • 设置 bulkActions 为 1000
  • 设置 bulkSize 为 5MB
  • 不设置 flushInterval
  • 设置 concurrentRequests 为 1,意味着每个 bulk 请都会进行异步刷新操作
  • 将补偿策略设置为指数补偿类型,8 次重试,并开始延迟 50 毫秒。总等待时间约为 5.1 秒

Add requests

你可以很轻松的向 BulkProcessor 中添加请求

bulkProcessor.add(new IndexRequest("twitter", "tweet", "1").source(/* your doc here */));
bulkProcessor.add(new DeleteRequest("twitter", "tweet", "2"));

Closing the Bulk Processor

当所有文档都加载到了 BulkProcessor.你可以通过使用 awaitClose 或 close 方法来关闭 BulkProcessor

bulkProcessor.awaitClose(10, TimeUnit.MINUTES);

或者

bulkProcessor.close();

Using Bulk Processor in tests

如果您正在使用 elasticsearch 进行测试,并且正在使用 BulkProcessor 来填充数据集,那么您应该更好地将并发请求的数量设置为 0,以便批量执行的刷新操作将以同步方式执行:

BulkProcessor bulkProcessor = BulkProcessor.builder(client, new BulkProcessor.Listener() { /* Listener methods */ })
        .setBulkActions(10000)
        .setConcurrentRequests(0)
        .build();

// Add your requests
bulkProcessor.add(/* Your requests */);

// Flush any remaining requests
bulkProcessor.flush();

// Or close the bulkProcessor if you don't need it anymore
bulkProcessor.close();

// Refresh your indices
client.admin().indices().prepareRefresh().get();

// Now you can start searching!
client.prepareSearch().get();

Search API

查询 API 允许我们执行一个查询 query 来获取命中的匹配结果.该 API 能在一个或多个索引上以及一个或多个类型上执行.你可以使用查询 Java API 来构建你的查询.查询请求的构建是使用 SearchSourceBuilder 来完成.比如下面的例子:

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.index.query.QueryBuilders.*;
SearchResponse response = client.prepareSearch("index1", "index2")
        .setTypes("type1", "type2")
        .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
        .setQuery(QueryBuilders.termQuery("multi", "test"))                 // Query
        .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))     // Filter
        .setFrom(0).setSize(60).setExplain(true)
        .get();

请注意,所有的参数都是可选的.下面是你可以最小化的请求

// MatchAll on the whole cluster with all default options
SearchResponse response = client.prepareSearch().get();

尽管 Java API 定义了额外的查询类型 QUERY_AND_FETCH 和 DFS_QUERY_AND_FETCH,但是这些模型内部都是最佳化的,你不应该尝试通过 API 来明确的指定这些类型.

想了解更多关于查询操作的信息,请参考:search

Using scrolls in Java

请先阅读 scroll documentation.

import static org.elasticsearch.index.query.QueryBuilders.*;

QueryBuilder qb = termQuery("multi", "test");

SearchResponse scrollResp = client.prepareSearch(test)
        .addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)
        .setScroll(new TimeValue(60000))
        .setQuery(qb)
        .setSize(100).get(); //max of 100 hits will be returned for each scroll
//Scroll until no hits are returned
do {
    for (SearchHit hit : scrollResp.getHits().getHits()) {
        //Handle the hit...
    }

    scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
} while(scrollResp.getHits().getHits().length != 0); // Zero hits mark the end of the scroll and the while loop.

MultiSearch API

请参考:MultiSearch API Query

该例子可以用来合并两个查询结果:

SearchRequestBuilder srb1 = client
    .prepareSearch().setQuery(QueryBuilders.queryStringQuery("elasticsearch")).setSize(1);
SearchRequestBuilder srb2 = client
    .prepareSearch().setQuery(QueryBuilders.matchQuery("name", "kimchy")).setSize(1);

MultiSearchResponse sr = client.prepareMultiSearch()
        .add(srb1)
        .add(srb2)
        .get();

// You will get all individual responses from MultiSearchResponse#getResponses()
long nbHits = 0;
for (MultiSearchResponse.Item item : sr.getResponses()) {
    SearchResponse response = item.getResponse();
    nbHits += response.getHits().getTotalHits();
}

Using Aggregations

下面的例子为我们展示在查询中添加两条聚合:

SearchResponse sr = client.prepareSearch()
    .setQuery(QueryBuilders.matchAllQuery())
    .addAggregation(
            AggregationBuilders.terms("agg1").field("field")
    )
    .addAggregation(
            AggregationBuilders.dateHistogram("agg2")
                    .field("birth")
                    .dateHistogramInterval(DateHistogramInterval.YEAR)
    )
    .get();

// Get your facet results
Terms agg1 = sr.getAggregations().get("agg1");
Histogram agg2 = sr.getAggregations().get("agg2");

了解更加详细内容请参考: Aggregations Java API

Terminate After

每个分片所能收集到的最大文档数量,在到达查询执行时将提前终止.如果设置,您将能够检查该操作是否提前终止,并在 SearchResponse 中请求 isTerminatedEarly()方法

SearchResponse sr = client.prepareSearch(INDEX)
    .setTerminateAfter(1000)   1
    .get();

if (sr.isTerminatedEarly()) {
    // We finished early
}
  1. 在查询到 1000 个文档之后会提前终止查询

Search Template

请参考文档 Search Template

用 Map<Strig,IObject> 定义你的模板参数:

Map template_params = new HashMap<>();
template_params.put("param_gender", "male");

你可以存储查询模板在 config/scripts 目录下.比如,如果你定义一个名称为 config/scripts/template_gender.mustache 包含

{
    "query" : {
        "match" : {
            "gender" : "{{param_gender}}"
        }
    }
}

创建你的模板请求:

SearchResponse sr = new SearchTemplateRequestBuilder(client)
    .setScript("template_gender")               1
    .setScriptType(ScriptService.ScriptType.FILE)2
    .setScriptParams(template_params)            3
    .setRequest(new SearchRequest())              4
    .get()                                       5
    .getResponse();
  1. 模板名称
  2. 模板存储在磁盘上的 gender_template.mustache
  3. 参数
  4. 设置执行上下文(比如在这里定义一个索引名称)
  5. 执行和获取模板请
  6. 从模板响应中获取搜索响应本身

你同样可以存储你的模板在集群状态中

client.admin().cluster().preparePutStoredScript()
    .setScriptLang("mustache")
    .setId("template_gender")
    .setSource(new BytesArray(
        "{\n" +
        "    \"query\" : {\n" +
        "        \"match\" : {\n" +
        "            \"gender\" : \"{{param_gender}}\"\n" +
        "        }\n" +
        "    }\n" +
        "}")).get();

为了执行一个存储的模板,请使用 ScriptService.ScriptType.STORED

SearchResponse sr = new SearchTemplateRequestBuilder(client)
        .setScript("template_gender")                     1
        .setScriptType(ScriptType.STORED)     2
        .setScriptParams(template_params)                   3
        .setRequest(new SearchRequest())                   4
        .get()                                             5
        .getResponse();
  1. 模板名称
  2. 将模板存储在集群状态中
  3. 参数
  4. 设置执行上下文(比如在这里定义一个索引名称)
  5. 执行和获取模板请
  6. 从模板响应中获取搜索响应本身

你同样能执行 inline 模板

sr = new SearchTemplateRequestBuilder(client)
        .setScript("{\n" +                                  1
                "        \"query\" : {\n" +
                "            \"match\" : {\n" +
                "                \"gender\" : \"{{param_gender}}\"\n" +
                "            }\n" +
                "        }\n" +
                "}")
        .setScriptType(ScriptType.INLINE)   2
        .setScriptParams(template_params)                 3
        .setRequest(new SearchRequest())                  4
        .get()                                           5
        .getResponse();
  1. 模板名称
  2. 设置内联模板
  3. 参数
  4. 设置执行上下文(比如在这里定义一个索引名称)
  5. 执行和获取模板请
  6. 从模板响应中获取搜索响应本身

Aggregations

Elasticsearch 提供一个全面的 Java API 来玩耍聚合(aggregations).请参考: Aggregations guide

将工厂用于聚合构建器(聚合构建器),并在查询时添加您想要计算的每个聚合,并将其添加到搜索请求:

SearchResponse sr = node.client().prepareSearch()
        .setQuery( /* your query */ )
        .addAggregation( /* add an aggregation */ )
        .execute().actionGet();

请注意你可以添加不止一个聚合.详细内容请参考:Search Java API

为了构建聚合请求,请使用 AggregationBuilders 辅助类.请在你的类中导入他们

import org.elasticsearch.search.aggregations.AggregationBuilders;

Structuring aggregations

根据 Aggregations guide 的解释,你可以在一个聚合内部构建子聚合.

一个聚合能够包含指标聚合或桶聚合.

例如,下面的例子由三种不同级别的聚合构成

  • terms 聚合(桶聚合)
  • 日期直方图聚合(桶聚合)
  • 平均值聚合(指标聚合)
SearchResponse sr = node.client().prepareSearch()
    .addAggregation(
        AggregationBuilders.terms("by_country").field("country")
        .subAggregation(AggregationBuilders.dateHistogram("by_year")
            .field("dateOfBirth")
            .dateHistogramInterval(DateHistogramInterval.YEAR)
            .subAggregation(AggregationBuilders.avg("avg_children").field("children"))
        )
    )
    .execute().actionGet();

Metrics aggregations

Min Aggregation

最小值(桶)聚合

1. Prepare aggregation request

这里有一个例子关于如何构建一个最小值聚合(桶聚合)请求

MinAggregationBuilder aggregation =
        AggregationBuilders
                .min("agg")
                .field("height");

2. Use aggregation response

导入聚合定义类

import org.elasticsearch.search.aggregations.metrics.min.Min;
Min agg = sr.getAggregations().get("agg");
double value = agg.getValue();

Max Aggregation

这里有关你如何使用 Max Aggregation 的 Java API

1. Prepare aggregation request

这里有一个例子关于如何构建一个最大值聚合(桶聚合)请求

MaxAggregationBuilder aggregation =
        AggregationBuilders
                .max("agg")
                .field("height");

2. Use aggregation response

导入聚合定义类

import org.elasticsearch.search.aggregations.metrics.max.Max;
// sr is here your SearchResponse object
Max agg = sr.getAggregations().get("agg");
double value = agg.getValue();

Sum Aggregation

这里有关你如何使用 Sum Aggregation

1. Prepare aggregation request

这里有一个例子关于如何构建一个求和聚合(桶聚合)请求

SumAggregationBuilder aggregation =
        AggregationBuilders
                .sum("agg")
                .field("height");

2. Use aggregation response
导入聚合定义类

import org.elasticsearch.search.aggregations.metrics.sum.Sum;
// sr is here your SearchResponse object
Sum agg = sr.getAggregations().get("agg");
double value = agg.getValue();

Avg Aggregation

这里有关你如何使用 Avg Aggregation

1. Prepare aggregation request
这里有一个例子关于如何构建一个均值聚合(桶聚合)请求

AvgAggregationBuilder aggregation =
        AggregationBuilders
                .avg("agg")
                .field("height");

2. Use aggregation response
导入聚合定义类

import org.elasticsearch.search.aggregations.metrics.avg.Avg;
// sr is here your SearchResponse object
Avg agg = sr.getAggregations().get("agg");
double value = agg.getValue();

Stats Aggregation

这里有关你如何使用 Stats Aggregation

1. Prepare aggregation request

这里有一个例子关于如何构建一个统计聚合(桶聚合)请求

StatsAggregationBuilder aggregation =
        AggregationBuilders
                .stats("agg")
                .field("height");

2. Use aggregation response
导入聚合定义类

import org.elasticsearch.search.aggregations.metrics.stats.Stats;
// sr is here your SearchResponse object
Stats agg = sr.getAggregations().get("agg");
double min = agg.getMin();
double max = agg.getMax();
double avg = agg.getAvg();
double sum = agg.getSum();
long count = agg.getCount();

Extended Stats Aggregation

1. Prepare aggregation request

2. Use aggregation response

Value Count Aggregation

1. Prepare aggregation request

2. Use aggregation response

Percentile Aggregation

1. Prepare aggregation request

2. Use aggregation response

Percentile Ranks Aggregation

1. Prepare aggregation request

2. Use aggregation response

Cardinality Aggregation

1. Prepare aggregation request

2. Use aggregation response

Geo Bounds Aggregation

1. Prepare aggregation request

2. Use aggregation response

Top Hits Aggregation

1. Prepare aggregation request

2. Use aggregation response

Scripted Metric Aggregation

1. Prepare aggregation request

2. Use aggregation response

Bucket aggregations

Query DSL

Elasticsearch 提供一个与 REST Query DSL 类似的非常全面的 java query dsl API.构建查询构造器的工厂类是 QueryBuilders.一旦你的查询准备好了,你就可以使用 Search API.

为了使用 QueryBuilders,只需要导入相关的类

import static org.elasticsearch.index.query.QueryBuilders.*;

请注意,你可以使用以 JSON 的格式通过调用 QueryBuilder 对象的 toString()方法而生成的查询语句来打印查询语句.

QueryBuilder 能够被任何能接收一个查询的 API 所使用,比如 count and search.

Match All Query

请参考:Match All Query

matchAllQuery();

Full text queries

高级全文查询通常在那些全文字段上进行查询比如 email 中 body 字段.在执行之前,它们理解每个要查询的字段是如何被分析以及在每个字段上使用哪种查询分析器(对于 search_analyzer)

该分类下有如下查询

执行全文查询的标准查询,包括模糊匹配和短语或邻近查询

match query 的多字段查询版本

一个更专业的查询,更倾向于不常见的单词。

支持紧凑的 Lucene 查询字符串语法,允许您在单个查询字符串中指定 AND|OR|NOT 条件,以及多字段搜索.该语法适合专家级别的用户使用

query_string 语法的一个更简单、更健壮的版本,适合直接暴露给用户使用

Match Query

请参考:Match Query

matchQuery(
        "name",                                              1
        "kimchy elasticsearch");                             2
  1. 字段名称
  2. 字段内容

Multi Match Query

请参考:Multi Match Query

multiMatchQuery(
        "kimchy elasticsearch",                              1
        "user", "message");                                  2
  1. 多字段内容
  2. 字段名称

Common Terms Query

请参考:Common Terms Query

commonTermsQuery("name",                                     1
                 "kimchy");                                  2
  1. 字段
  2. 字段值

Query String Query

请参考:Query String Query

queryStringQuery("+kimchy -elasticsearch");

Simple Query String Query

请参考: Simple Query String Query

请参考: Simple Query String Query

simpleQueryStringQuery("+kimchy -elasticsearch");

Term level queries

full text queries 在执行之前,会分析查询的字符串
,但是词项级别(term-level)的查询操作,会在倒排索引中进行精确匹配.

这些查询通常用于结构化数据,如数字、日期和枚举,而不是完整的文本字段。或者,它们允许您进行低级查询,而不是分析过程.

该分组下的查询包含:

  • term query

    查找在指定的字段上必须包含指定 term 的文档集合

  • terms query

    查找在指定的字段上包含指定 terms 中的任意一个 term 的文档集合

  • range query

    查找符合在指定字段上的范围间的文档集合,字段类型可以是日期,数字,或字符串

  • exists query

    查找字段值不为空值类型(non-null)的文档集合

  • prefix query

    查找包含以指定前缀开头的 term 的文档集合

  • wildcard query

    查找包含指定 term 且与指定模式匹配的文档集合,该模式支持单个字符通配符(?)和多字符通配符(*)

  • regexp query

    查找符合指定正则表达式的 term 的文档集合

  • fuzzy query

    查找那些包含指定 term 且符合指定空间编辑距离(Levenshtein edit distance)的 term 的文档集合,空间距离一般为 1 或 2

  • type query

    在指定类型下查找文档

  • ids query

    通过指定 ID 和类型来查找文档

Term Query

请参考:Term Query

termQuery(
        "name",                                              1
        "kimchy");                                           2

1.字段名称
2. 查询文本

Terms Query

请参考:Terms Query

termsQuery("tags",                                           1
        "blue", "pill");                                     2
  1. 字段
  2. 文本值

Range Query

请参考:Range Query

rangeQuery("price")                                          1
    .from(5)                                                 2
    .to(10)                                                  3
    .includeLower(true)                                      4
    .includeUpper(false);                                    5

  1. 字段
  2. from
  3. to
  4. 是否包含 from 的边界值,设置 true 则等效于 gte,如果为 false 则等效于 gt
  5. 是否包含 to 的边界值,设置 true 则等效于 lte,如果为 false 则等效于 lt
// A simplified form using gte, gt, lt or lte
rangeQuery("age")                                             1
    .gte("10")                                                2
    .lt("20");                                                3
  1. 字段
  2. 等效于设置 from 为 10 且 includeLower 为 true
  3. 等效于设置 to 为 20 且 includeUpper 为 false

Exists Query

请参考:Exists Query.

existsQuery("name"); 1
  1. 字段

Prefix Query

请参考:Prefix Query

prefixQuery(
        "brand",                                             1
        "heine");                                            2
  1. 字段
  2. 前缀

Wildcard Query

请参考:Wildcard Query

wildcardQuery(
        "user",                                              1
        "k?mch*");                                           2
  1. 字段
  2. 通配符表达式

Regexp Query

请参考:Regexp Query

regexpQuery(
        "name.first",                                        1
        "s.*y");                                             2
  1. 字段
  2. 正则

Fuzzy Query

请参考: Fuzzy Query

fuzzyQuery(
        "name",                                              1
        "kimchy");                                           2
  1. 字段
  2. 文本

Type Query

请参考: Type Query

typeQuery("my_type");                                        1
  1. 类型

Ids Query

请参考:Ids Query

idsQuery("my_type", "type2")
        .addIds("1", "4", "100");

idsQuery()                                                   1
        .addIds("1", "4", "100");
  1. 类型是可选的

Compound queries

符合查询包装其他符合查询或子查询,或者结合他们的结果和评分,来改变他们原有的行为,或者从查询切换到过滤上下文。

该分组下的查询包含:

Joining queries

Geo queries

Specialized queries

Span queries

Indexed Scripts API

索引脚本 API 允许在 Elasticsearch 索引中设置一个有影响的脚本或模板.它能够被用来 create,update,get 或 delete 脚本或模板

PutIndexedScriptResponse = client.preparePutIndexedScript()
                         .setScriptLang("painless")
                         .setId("script1")
                         .setSource("script", "_score * doc['my_numeric_field'].value")
                         .execute()
                         .actionGet();

GetIndexedScriptResponse = client.prepareGetIndexedScript()
                            .setScriptLang("painless")
                            .setId("script1")
                            .execute()
                            .actionGet();

DeleteIndexedScriptResponse = client.prepareDeleteIndexedScript()
                            .setScriptLang("painless")
                            .setId("script1")
                            .execute()
                            .actionGet();

如果想存储模板,请简单地使用“mustache”作为脚本语言

Script Language

索引脚本 API 允许为索引脚本设置一种脚本语言。如果没有提供脚本语言,则将使用默认的脚本语言.

Java API Administration

Indices Administration

Cluster Administration

  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    116 引用 • 99 回帖 • 266 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...