博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ElasticSearch6.5.0 【Java客户端之REST Client】
阅读量:6879 次
发布时间:2019-06-26

本文共 125549 字,大约阅读时间需要 418 分钟。

说明

High Level Client 是基于 Low Level Client 的。官方文档如下:

* *

 依赖

org.elasticsearch.client
transport
6.5.0
org.apache.logging.log4j
log4j-core
2.11.1
org.apache.logging.log4j
log4j-to-slf4j
2.11.1
org.slf4j
slf4j-api
1.7.25
org.elasticsearch.client
elasticsearch-rest-client
6.5.0
org.elasticsearch.client
elasticsearch-rest-high-level-client
6.5.0

 连接

import org.apache.http.HttpHost;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;/** * Java高级REST客户机在Java低级REST客户机之上工作。它的主要目标是公开特定于API的方法,这些方法接受请求对象作为参数并返回响应对象 * 可以同步或异步调用每个API。同步方法返回一个响应对象,而异步方法(其名称以async后缀结尾)需要一个侦听器参数 * 一旦接收到响应或错误,侦听器参数(在低层客户机管理的线程池上)将被通知。 * Java高级REST客户机依赖于Elasticsearch核心项目。它接受与TransportClient相同的请求参数,并返回相同的响应对象。 * Java高级REST客户机需要Java 1.8 * 客户机版本与开发客户机的Elasticsearch版本相同 * 6.0客户端能够与任意6.X节点通信,6.1客户端能够与6.1、6.2和任意6.X通信 */public class RestClientFactory {    private RestClientFactory(){}    private static class Inner{        private static final RestClientFactory instance = new RestClientFactory();    }    public static RestClientFactory getInstance(){        return Inner.instance;    }    public RestHighLevelClient getClient(){        RestHighLevelClient client = new RestHighLevelClient(                RestClient.builder(                        //new HttpHost("localhost", 9201, "http"),                        new HttpHost("localhost", 9200, "http")                )        );        return client;    }}

【JavaAPI与HTTP请求】

1. Index

HTTP请求

查看所有数据GET twitter/t_doc/_search

---

# 添加数据[index]/[type]/[id]PUT twitter/t_doc/10{
"user" : "kimchy", "post_date" : "2018-12-24T11:32:00", "message" : "trying out Elasticsearch"}

结果:

{  "_index" : "twitter",  "_type" : "t_doc",  "_id" : "10",  "_version" : 1,  "result" : "created",  "_shards" : {    "total" : 2,    "successful" : 1,    "failed" : 0  },  "_seq_no" : 0,  "_primary_term" : 1}

Java 

public static RestHighLevelClient index() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        Map
jsonMap = new HashMap<>(); jsonMap.put("user", "kimchy"); jsonMap.put("postDate", new Date()); jsonMap.put("message", "trying out Elasticsearch"); IndexRequest indexRequest = new IndexRequest("twitter", "t_doc", "1") .source(jsonMap); IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT); System.out.println(response.status().name()); return client; }

结果:

CREATED

还有两种形式添加数据

/**     * 方式二:XContentBuilder     * @return     * @throws IOException     */    public static RestHighLevelClient index2() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        XContentBuilder builder = jsonBuilder();        builder.startObject();        {            builder.field("user", "kimchy");            builder.timeField("postDate", new Date());            builder.field("message", "trying out Elasticsearch");        }        builder.endObject();        IndexRequest indexRequest = new IndexRequest("twitter", "t_doc", "2")                .source(builder);        IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);        System.out.println(response.status().name());        return client;    }    /**     * 方式三:Object key-pairs对象键     * 同步方法     * @return     * @throws IOException     */    public static RestHighLevelClient index3() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        IndexRequest indexRequest = new IndexRequest("twitter", "t_doc", "3")                .source("user", "kimchy",                        "postDate", new Date(),                        "message", "trying out Elasticsearch");        IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);    // 同步方式        System.out.println(response.status().name());        return client;    }

还能异步创建&添加数据

/**     * 异步方法     * @return     * @throws IOException     */    public static RestHighLevelClient index4() throws IOException, InterruptedException {        ActionListener listener = new ActionListener
() { @Override public void onResponse(IndexResponse indexResponse) { System.out.println("Async:" + indexResponse.status().name()); if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) { // Todo } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) { // Todo } // 处理成功分片小于总分片的情况 ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo(); if (shardInfo.getTotal() != shardInfo.getSuccessful()) { // Todo } } @Override public void onFailure(Exception e) { System.out.println("AsyncFailure:" + e.getMessage()); e.printStackTrace(); } }; RestHighLevelClient client = RestClientFactory.getInstance().getClient(); IndexRequest indexRequest = new IndexRequest("twitter", "t_doc", "4") .source("user", "kimchy", "postDate", new Date(), "message", "trying out Elasticsearch") .routing("my_route"); // 指定路由 client.indexAsync(indexRequest, RequestOptions.DEFAULT, listener); // 异步方式 Thread.sleep(2000); return client; }

结果:

Async:CREATED

 2. Get

 HTTP请求

# 获取数据GET twitter/t_doc/1结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "1", "_version" : 1, "found" : true, "_source" : { "postDate" : "2018-12-24T03:42:22.787Z", "message" : "trying out Elasticsearch", "user" : "kimchy" }}

 

可以指定routing

GET twitter/t_doc/4?routing=my_route结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "4", "_version" : 1, "_routing" : "my_route", "found" : true, "_source" : { "user" : "kimchy", "postDate" : "2018-12-24T06:08:45.178Z", "message" : "trying out Elasticsearch" }}

 

可以只要数据信息_source

GET twitter/t_doc/4/_source?routing=my_route结果:{
"user" : "kimchy", "postDate" : "2018-12-24T06:08:45.178Z", "message" : "trying out Elasticsearch"}

 

Java

public static RestHighLevelClient getOne() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetRequest request = new GetRequest("twitter", "t_doc", "4").routing("my_route");   // 指定routing的数据,查询也要指定        try {            GetResponse response = client.get(request, RequestOptions.DEFAULT);            System.out.println(response.getSourceAsString());        } catch (ElasticsearchException e) {            // 处理找不到index的异常            if(e.status() == RestStatus.NOT_FOUND){                // TODO            }        }        return client;    }

结果:

{"user":"kimchy","postDate":"2018-12-24T06:08:45.178Z","message":"trying out Elasticsearch"}

 

 异步获取,并且指定包含/排除的字段

/**     * 查询-额外参数     * 异步获取     * @return     * @throws IOException     */    public static RestHighLevelClient getOneOp() throws IOException, InterruptedException {        ActionListener
listener = new ActionListener
() { @Override public void onResponse(GetResponse documentFields) { System.out.println(documentFields.getSourceAsString()); } @Override public void onFailure(Exception e) { System.out.println("Error:" + e.getMessage()); e.printStackTrace(); } }; RestHighLevelClient client = RestClientFactory.getInstance().getClient(); GetRequest request = new GetRequest("twitter", "t_doc", "1"); String[] includes = new String[]{"message", "*Date"}; // 包含的字段 String[] excludes = Strings.EMPTY_ARRAY; // 排除的字段 FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); request.fetchSourceContext(fetchSourceContext); client.getAsync(request, RequestOptions.DEFAULT, listener); Thread.sleep(2000); return client; }

结果:

{"postDate":"2018-12-24T03:42:22.787Z","message":"trying out Elasticsearch"}

 

到这里也应该知道,Rest API 对每个操作提供了同步/异步的方法。

3. Exist API

Java

/**     * 检查是否存在     * @return     * @throws IOException     */    public static RestHighLevelClient exist() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetRequest request = new GetRequest("twitter", "t_doc", "1");        request.storedFields("_none_"); // 禁用获取存储字段        request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE); // 禁用抓取_source        boolean exists = client.exists(request, RequestOptions.DEFAULT);        System.out.println(exists);        return client;    }

结果:

true

4.  Delete API

HTTP请求

DELETE twitter/t_doc/1结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "1", "_version" : 2, "result" : "deleted", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 1, "_primary_term" : 1}

 

Java

/**     * 删除也可以异步、也可以捕获异常,成功删除的分片数量,版本冲突     * @return     * @throws IOException     */    public static RestHighLevelClient deleteOne() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        DeleteRequest request = new DeleteRequest("twitter", "t_doc", "1");        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);        System.out.println(response.status().name());        // 处理找不到的情况        if (response.getResult() == DocWriteResponse.Result.NOT_FOUND) {            // TODO        }        return client;    }

结果:

NOT_FOUND

5. Delete By Query API

我这里有4条测试数据

{
"user":"Tom","flag":"1"}{
"user":"foo","flag":"2"}{
"user":"bar","flag":"2"}{
"user":"baz","flag":"2"}

 

HTTP 请求

# 删除flag=2的数据POST twitter/_delete_by_query?conflicts=proceed{
"query": { "match": { "flag": "2" } }}结果:{
"took" : 183, "timed_out" : false, "total" : 3, "deleted" : 3, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ]}

 --扩展

# 清空索引全部数据POST /[索引名]/_delete_by_query{
"query": { "match_all": {
} }}

 

Java

/**     * 根据查询条件删除     * @return     * @throws IOException     */    public static RestHighLevelClient deleteByQuery() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        DeleteByQueryRequest request = new DeleteByQueryRequest("twitter");        request.setConflicts("proceed");    // 发生冲突即略过        request.setQuery(QueryBuilders.matchQuery("flag","2"));        BulkByScrollResponse bulkResponse = client.deleteByQuery(request, RequestOptions.DEFAULT);        TimeValue timeTaken = bulkResponse.getTook();        boolean timedOut = bulkResponse.isTimedOut();        long totalDocs = bulkResponse.getTotal();        long updatedDocs = bulkResponse.getUpdated();        long deletedDocs = bulkResponse.getDeleted();        long batches = bulkResponse.getBatches();        long noops = bulkResponse.getNoops();        long versionConflicts = bulkResponse.getVersionConflicts();        System.out.println("花费时间:" + timeTaken + ",是否超时:" + timedOut + ",总文档数:" + totalDocs + ",更新数:" +                updatedDocs + ",删除数:" + deletedDocs + ",批量次数:" + batches + ",跳过数:" + noops + ",冲突数:" + versionConflicts);        List
searchFailures = bulkResponse.getSearchFailures(); // 搜索期间的故障 searchFailures.forEach(e -> { System.err.println("Cause:" + e.getReason().getMessage() + "Index:" + e.getIndex() + ",NodeId:" + e.getNodeId() + ",ShardId:" + e.getShardId()); }); List
bulkFailures = bulkResponse.getBulkFailures(); // 批量索引期间的故障 bulkFailures.forEach(e -> { System.err.println("Cause:" + e.getCause().getMessage() + "Index:" + e.getIndex() + ",Type:" + e.getType() + ",Id:" + e.getId()); }); return client; }

结果:

花费时间:97ms,是否超时:false,总文档数:3,更新数:0,删除数:3,批量次数:1,跳过数:0,冲突数:0

6. Update API

我有一条测试数据

{
"user":"Tom","flag":"1"}

 

HTTP 请求

# 通过脚本更新POST twitter/t_doc/1/_update{
"script" : { "source": "ctx._source.msg = params.msg", "lang": "painless", "params" : { "msg" : "達に携帯で連絡取ろうと思ったら 電池が切れてて動かない" } }}# 通过文档更新POST twitter/t_doc/1/_update{
"doc" : { "user" : "new_name" }}

 

upserts

# upserts(如果文档不存在,则把upsert里面的内容作为文档插入)POST twitter/t_doc/2/_update{
"script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } }, "upsert" : {
"counter" : 1 }}结果【创建新文档】:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "2", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 1, "_primary_term" : 1}

 

如果你再执行的话就是更新了

结果【更新文档】:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "2", "_version" : 2, "result" : "updated", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 2, "_primary_term" : 1}查询:GET twitter/t_doc/2结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "2", "_version" : 2, "found" : true, "_source" : { "counter" : 5 }}

 

不用脚本而用文档更新

# 如果文档不存在,则将doc内容作为新文档插入(因为"doc_as_upsert" : true)POST twitter/t_doc/3/_update{
"doc" : { "name" : "new_name" }, "doc_as_upsert" : true}结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "3", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 5, "_primary_term" : 1}查询:GET twitter/t_doc/3结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "3", "_version" : 1, "found" : true, "_source" : { "name" : "new_name" }}

 

Java

/**     * 通过脚本更新,可以添加字段     * @return     */    public static RestHighLevelClient updateOne() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        UpdateRequest request = new UpdateRequest("twitter", "t_doc", "1");        Map
parameters = singletonMap("msg", "達に携帯で連絡取ろうと思ったら 電池が切れてて動かない"); Script inline = new Script(ScriptType.INLINE, "painless", "ctx._source.msg = params.msg", parameters); request.script(inline); UpdateResponse update = client.update(request, RequestOptions.DEFAULT); System.out.println(update.status().name()); return client; }

输出:OK

GET twitter/t_doc/1结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "1", "_version" : 4, "found" : true, "_source" : { "user" : "Tom", "flag" : "1", "msg" : "達に携帯で連絡取ろうと思ったら 電池が切れてて動かない" }}

 

还可以通过XContentBuilder

/**     * 通过XContentBuilder更新     * @return     * @throws IOException     */    public static RestHighLevelClient updateOne2() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        XContentBuilder builder = jsonBuilder()                .startObject()                    .startObject("animal")                        .field("cat", "阿猫")                        .field("dog", "阿狗")                    .endObject()                .endObject();        UpdateRequest request = new UpdateRequest("twitter", "t_doc", "1").doc(builder);        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);        System.out.println(update.status().name());        return client;    }

输出:OK

GET twitter/t_doc/1结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "1", "_version" : 5, "found" : true, "_source" : { "user" : "Tom", "flag" : "1", "msg" : "達に携帯で連絡取ろうと思ったら 電池が切れてて動かない", "animal" : { "cat" : "阿猫", "dog" : "阿狗" } }}

还可以通过Map

/**     * 通过jsonMap更新     * @return     * @throws IOException     */    public static RestHighLevelClient updateOne3() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        Map
jsonMap = new HashMap<>(); jsonMap.put("updateUser", "Jack Ma"); UpdateRequest request = new UpdateRequest("posts", "doc", "1").doc(jsonMap); UpdateResponse update = client.update(request, RequestOptions.DEFAULT); System.out.println(update.status().name()); return client; }

输出:OK

GET twitter/t_doc/1结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "1", "_version" : 6, "found" : true, "_source" : { "user" : "Tom", "flag" : "1", "msg" : "達に携帯で連絡取ろうと思ったら 電池が切れてて動かない", "animal" : { "cat" : "阿猫", "dog" : "阿狗" }, "updateUser" : "Jack Ma" }}

还可以通过 key-pairs

/**     * 通过 key-pairs 更新     * @return     * @throws IOException     */    public static RestHighLevelClient updateOne4() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        UpdateRequest request = new UpdateRequest("twitter", "t_doc", "1")                .doc("favorite","二狗","hate","no Money");        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);        System.out.println(update.status().name());        return client;    }

输出:OK

GET twitter/t_doc/1结果:{
"_index" : "twitter", "_type" : "t_doc", "_id" : "1", "_version" : 7, "found" : true, "_source" : { "user" : "Tom", "flag" : "1", "msg" : "達に携帯で連絡取ろうと思ったら 電池が切れてて動かない", "animal" : { "cat" : "阿猫", "dog" : "阿狗" }, "updateUser" : "Jack Ma", "hate" : "no Money", "favorite" : "二狗" }}

upserts

/**     * 存在即更新【输出:OK】     * OK     * {"C":"Carambola","A":"Apple","B":"Banana"}     * 不存在则创建【输出:CREATED】     * CREATED     * {"C":"Carambola"}     * 开启scriptedUpsert【在文档不存在情况下输出:CREATED】     * {"A" : "Apple","B" : "Banana","C" : "Carambola"}     * @return     * @throws IOException     */    public static RestHighLevelClient upserts() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        UpdateRequest request = new UpdateRequest("twitter", "t_doc", "7")                .script(new Script(ScriptType.INLINE,"painless",                        "ctx._source.A='Apple';ctx._source.B='Banana'",Collections.EMPTY_MAP))                // 如果文档不存在,使用upsert方法定义一些内容,这些内容将作为新文档插入                .upsert(jsonBuilder()                    .startObject()                    .field("C","Carambola")                    .endObject());        request.timeout(TimeValue.timeValueSeconds(2)); // 2秒超时        //request.scriptedUpsert(true);   // 无论文档是否存在,脚本都必须运行        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);        System.out.println(update.status().name());        return client;    }

--

/**     * 存在即更新     * OK     * {"C" : "Carambola","A" : "Apple","B" : "Banana","D" : "Dew"}     * 不存在则创建     * CREATED     * {"C" : "Carambola"}     * 开启docAsUpsert【在文档不存在情况下输出:CREATED】     * {"A" : "Apple","B" : "Banana","D" : "Dew"}     * @return     * @throws IOException     */    public static RestHighLevelClient upserts2() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        UpdateRequest request = new UpdateRequest("twitter", "t_doc", "8")                .doc(jsonBuilder()                    .startObject()                    .field("A","Apple")                    .field("B","Banana")                    .field("D","Dew")                    .endObject())                // 如果指定docAsUpsert(true),会忽略upsert方法                .upsert(jsonBuilder()                    .startObject()                    .field("C","Carambola")                    .endObject());        //request.docAsUpsert(true);  // 如果部分文档尚不存在,则必须将doc用作upsert文档        request.timeout(TimeValue.timeValueSeconds(2)); // 2秒超时        try {            UpdateResponse update = client.update(request, RequestOptions.DEFAULT);            System.out.println(update.status().name());        } catch (ElasticsearchException e) {            if (e.status() == RestStatus.NOT_FOUND) {                // TODO            }        }        return client;    }

7. Update By Query API

HTTP请求

# 不更改源数据的前提下更新文档POST twitter/_update_by_query?conflicts=proceed结果:{
"took" : 186, "timed_out" : false, "total" : 9, "updated" : 9, "deleted" : 0, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ]}

--

我们有数据:

{
"_index" : "twitter", "_type" : "t_doc", "_id" : "9", "_version" : 3, "found" : true, "_source" : { "flag" : "2", "user" : "foo" }}

 

# 通过脚本更新POST twitter/_update_by_query?conflicts=proceed{
"script": { "source": "ctx._source.flag++", "lang": "painless" }, "query": {
"term": { "user": "foo" } }}结果:{
"took" : 102, "timed_out" : false, "total" : 1, "updated" : 1, "deleted" : 0, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ]}

 

Java

/**     * 根据查询条件更新     * @return     */    public static RestHighLevelClient updateByQuery() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        UpdateByQueryRequest request = new UpdateByQueryRequest("twitter");        request.setConflicts("proceed");        request.setQuery(QueryBuilders.matchAllQuery())                .setBatchSize(50)   // 批处理大小                .setSize(100)      // 限制处理文档的数量                .setScript(new Script(                ScriptType.INLINE, "painless",                "if (ctx._source.flag == '2') {ctx._source.extMsg = '小林さんちのメイドラゴン';}", // 增加一个字段extMsg                Collections.emptyMap()));        BulkByScrollResponse bulkResponse = client.updateByQuery(request, RequestOptions.DEFAULT);        TimeValue timeTaken = bulkResponse.getTook();        boolean timedOut = bulkResponse.isTimedOut();        long totalDocs = bulkResponse.getTotal();        long updatedDocs = bulkResponse.getUpdated();        long deletedDocs = bulkResponse.getDeleted();        long batches = bulkResponse.getBatches();        long noops = bulkResponse.getNoops();        long versionConflicts = bulkResponse.getVersionConflicts();        System.out.println("花费时间:" + timeTaken + ",是否超时:" + timedOut + ",总文档数:" + totalDocs + ",更新数:" +                updatedDocs + ",删除数:" + deletedDocs + ",批量次数:" + batches + ",跳过数:" + noops + ",冲突数:" + versionConflicts);        List
searchFailures = bulkResponse.getSearchFailures(); // 搜索期间的故障 searchFailures.forEach(e -> { System.err.println("Cause:" + e.getReason().getMessage() + "Index:" + e.getIndex() + ",NodeId:" + e.getNodeId() + ",ShardId:" + e.getShardId()); }); List
bulkFailures = bulkResponse.getBulkFailures(); // 批量索引期间的故障 bulkFailures.forEach(e -> { System.err.println("Cause:" + e.getCause().getMessage() + "Index:" + e.getIndex() + ",Type:" + e.getType() + ",Id:" + e.getId()); }); return client; }

 

结果:【之所以更新了全部文档,是因为matchAllQuery】

花费时间:218ms,是否超时:false,总文档数:9,更新数:9,删除数:0,批量次数:1,跳过数:0,冲突数:0

 

# 查询flag=2的文档GET /twitter/_search{
"query": { "match": { "flag": "2" } }}结果:{
"took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 2, "max_score" : 0.6931472, "hits" : [ { "_index" : "twitter", "_type" : "t_doc", "_id" : "10", "_score" : 0.6931472, "_source" : { "flag" : "2", "extMsg" : "小林さんちのメイドラゴン", "user" : "bar" } }, {
"_index" : "twitter", "_type" : "t_doc", "_id" : "11", "_score" : 0.2876821, "_source" : { "flag" : "2", "extMsg" : "小林さんちのメイドラゴン", "user" : "baz" } } ] }}

8. Bulk API

HTTP请求

 

# 批量处理(允许Add,Delete,Update操作)如果包含routing要加上POST _bulk{
"delete" : { "_index" : "twitter", "_type" : "t_doc", "_id" : "9" } }{
"update" : { "_index" : "twitter", "_type" : "t_doc", "_id" : "4","routing":"my_route" } }{
"doc" : {"user":"new_user"} }{
"index" : { "_index" : "twitter", "_type" : "t_doc", "_id" : "21" }}{
"user":"Tom","flag":"1" }{
"index" : { "_index" : "twitter", "_type" : "t_doc", "_id" : "22" }}{
"user":"Tony","flag":"1" }{
"index" : { "_index" : "twitter", "_type" : "t_doc", "_id" : "23" }}{
"user":"Mary","flag":"1" }{
"index" : { "_index" : "twitter", "_type" : "t_doc", "_id" : "24" }}{
"user":"Jerry","flag":"1" }

Java

/**     * 批量添加     * @return     */    public static RestHighLevelClient bulkAdd() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        BulkRequest request = new BulkRequest();        request.add(new IndexRequest("twitter", "t_doc", "25")                .source(XContentType.JSON,"user", "Tom","flag","1"));        request.add(new IndexRequest("twitter", "t_doc", "26")                .source(XContentType.JSON,"user", "foo","flag","2"));        request.add(new IndexRequest("twitter", "t_doc", "27")                .source(XContentType.JSON,"user", "bar","flag","2"));        request.add(new IndexRequest("twitter", "t_doc", "28")                .source(XContentType.JSON,"user", "baz","flag","2"));        BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);        System.out.println("Status:" + bulk.status().name() + ",hasFailures:" + bulk.hasFailures());        // 下面是multiGet        MultiGetRequest multiGetRequest = new MultiGetRequest()                .add(new MultiGetRequest.Item("twitter", "t_doc", "25"))                .add(new MultiGetRequest.Item("twitter", "t_doc", "26"))                .add(new MultiGetRequest.Item("twitter", "t_doc", "27"))                .add(new MultiGetRequest.Item("twitter", "t_doc", "28"));        MultiGetResponse response = client.mget(multiGetRequest, RequestOptions.DEFAULT);        MultiGetItemResponse[] itemResponses = response.getResponses();        for(MultiGetItemResponse r : itemResponses){            System.out.println(r.getResponse().getSourceAsString());        }        return client;    }

输出:

Status:OK,hasFailures:false{
"user":"Tom","flag":"1"}{
"user":"foo","flag":"2"}{
"user":"bar","flag":"2"}{
"user":"baz","flag":"2"}

也可以批量更新

/**     * 批量更新     * @return     */    public static RestHighLevelClient bulkUpdate() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        BulkRequest request = new BulkRequest();        // 更新        request.add(new UpdateRequest("twitter", "t_doc", "27")                .doc(XContentType.JSON,"field", "foo","color", "red","size", "100"));        // 添加        request.add(new IndexRequest("twitter", "t_doc", "29")                .source(XContentType.JSON,"field", "bar","color", "blue","size", "200"));        // 删除        request.add(new DeleteRequest("twitter", "t_doc", "28"));        BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);        System.out.println("Status:" + bulk.status().name() + ",hasFailures:" + bulk.hasFailures());        // 针对不同类型进行处理        for (BulkItemResponse bulkItemResponse : bulk) {            DocWriteResponse itemResponse = bulkItemResponse.getResponse();            if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX                    || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) {                IndexResponse indexResponse = (IndexResponse) itemResponse;                System.out.println(indexResponse.status().name());            } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) {                UpdateResponse updateResponse = (UpdateResponse) itemResponse;                System.out.println(updateResponse.status().name());            } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) {                DeleteResponse deleteResponse = (DeleteResponse) itemResponse;                System.out.println(deleteResponse.status().name());            }        }        String[] includes = Strings.EMPTY_ARRAY;        String[] excludes = new String[] {"flag"};        // 包含/排除的字段        FetchSourceContext fetchSourceContext =                new FetchSourceContext(true, includes, excludes);        MultiGetRequest multiGetRequest = new MultiGetRequest()                .add(new MultiGetRequest.Item("twitter", "t_doc", "29").fetchSourceContext(fetchSourceContext))                .add(new MultiGetRequest.Item("twitter", "t_doc", "28").fetchSourceContext(fetchSourceContext))                .add(new MultiGetRequest.Item("twitter", "t_doc", "27").fetchSourceContext(fetchSourceContext));        MultiGetResponse response = client.mget(multiGetRequest, RequestOptions.DEFAULT);        MultiGetItemResponse[] itemResponses = response.getResponses();        for(MultiGetItemResponse r : itemResponses){            System.out.println(r.getResponse().getSourceAsString());        }        return client;    }

 

输出:

Status:OK,hasFailures:falseOKCREATEDOK{
"field":"bar","color":"blue","size":"200"}null{
"field":"foo","color":"red","size":"100","user":"bar"}

 

bulkProcessor就比较厉害了

/**     * BulkProcessor通过提供一个实用程序类来简化Bulk API的使用,它允许索引/更新/删除操作在添加到处理器时透明地执行。     * 为了执行请求,BulkProcessor需要以下组件:     * RestHighLevelClient     * 此客户端用于执行BulkRequest和检索BulkResponse     * BulkProcessor.Listener     * 在每个BulkRequest执行之前和之后,或者在BulkRequest失败时,都会调用这个侦听器     * BulkProcessor.builder方法可用于构建新的BulkProcessor:     * @return     */    public static RestHighLevelClient bulkProcessor() throws InterruptedException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        BulkProcessor.Listener listener = new BulkProcessor.Listener() {            @Override            public void beforeBulk(long executionId, BulkRequest request) {                int numberOfActions = request.numberOfActions();                System.out.println("请求数量:" + numberOfActions);            }            @Override            public void afterBulk(long executionId, BulkRequest request, BulkResponse response) {                if (response.hasFailures()) {                    System.out.println("Bulk Failures,ID:" + executionId + ",Status:" + response.status().name());                    for (BulkItemResponse bulkItemResponse : response) {                        if (bulkItemResponse.isFailed()) {                            BulkItemResponse.Failure failure = bulkItemResponse.getFailure();                            System.err.println(failure.getCause().getMessage());                        }                    }                } else {                    System.out.println("Bulk "+ executionId +" Complete in" + response.getTook().getMillis() + "s");                }            }            @Override            public void afterBulk(long executionId, BulkRequest request, Throwable failure) {                System.out.println("Failed to execute bulk:" + failure);            }        };        BiConsumer
> bulkConsumer = (request, bulkListener) -> client.bulkAsync(request, RequestOptions.DEFAULT, bulkListener); BulkProcessor bulkProcessor = BulkProcessor.builder(bulkConsumer, listener) .setBulkActions(500) // 请求(Index,Update,Delete)的数量达到500,就刷新一次bulk request【默认1000】// .setBulkSize(new ByteSizeValue(1L, ByteSizeUnit.MB)) // 累计请求所占的空间达到1M,就刷新一次bulk request【默认5M】 .setConcurrentRequests(0) // 设置允许执行的并发请求数量(默认为1,使用0只允许执行单个请求)// .setFlushInterval(TimeValue.timeValueSeconds(10L)) // 每隔一段时间刷新一次【默认未设置】 .setBackoffPolicy(BackoffPolicy .constantBackoff(TimeValue.timeValueSeconds(1L), 3))// 设置一个初始等待1秒并重试3次的Backoff策略 .build(); for(int i = 1; i <= 2000; i++){ bulkProcessor.add(new IndexRequest("books", "java", ""+i) .source(XContentType.JSON,"title","title_"+i,"user","user_"+i)); } bulkProcessor.flush(); Thread.sleep(2000); bulkProcessor.close(); return client; }

 

输出:【警告可忽略,因为默认分片数量在7.0.0版本会改变,这里提醒一下用户。也就是说,最好先去建立索引(设置好参数),再来添加数据】

请求数量:500十二月 25, 2018 11:24:06 上午 org.elasticsearch.client.RestClient logResponse警告: request [POST http://localhost:9200/_bulk?timeout=1m] returned 1 warnings: [299 Elasticsearch-6.5.0-816e6f6 "the default number of shards will change from [5] to [1] in 7.0.0; if you wish to continue using the default of [5] shards, you must manage this on the create index request or with an index template" "Tue, 25 Dec 2018 03:24:04 GMT"]Bulk 1 Complete in2044s请求数量:500Bulk 2 Complete in333s请求数量:500Bulk 3 Complete in235s请求数量:500Bulk 4 Complete in244s

 

 查看:

GET books/_search结果:{
"took" : 18, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 2000, "max_score" : 1.0, "hits" : [ { "_index" : "books", "_type" : "java", "_id" : "14", "_score" : 1.0, "_source" : { "title" : "title_14", "user" : "user_14" } }, .... ] }}

9. Multi-Get API

HTTP 请求 

GET /_mget{
"docs" : [ { "_index" : "books", "_type" : "java", "_id" : "1" }, {
"_index" : "twitter", "_type" : "t_doc", "_id" : "1" } ]}结果:{
"docs" : [ { "_index" : "books", "_type" : "java", "_id" : "1", "_version" : 1, "found" : true, "_source" : { "title" : "title_1", "user" : "user_1" } }, {
"_index" : "twitter", "_type" : "t_doc", "_id" : "1", "_version" : 13, "found" : true, "_source" : { "msg" : "達に携帯で連絡取ろうと思ったら 電池が切れてて動かない", "flag" : "1", "user" : "new_name" } } ]}
GET /twitter/t_doc/_mget{
"docs" : [ { "_id" : "1" }, {
"_id" : "2" } ]}GET /twitter/t_doc/_mget{
"ids" : ["1", "2"]}# 两个方式效果一样结果:{
"docs" : [ { "_index" : "twitter", "_type" : "t_doc", "_id" : "1", "_version" : 13, "found" : true, "_source" : { "msg" : "達に携帯で連絡取ろうと思ったら 電池が切れてて動かない", "flag" : "1", "user" : "new_name" } }, {
"_index" : "twitter", "_type" : "t_doc", "_id" : "2", "_version" : 5, "found" : true, "_source" : { "counter" : 5, "user" : "new_user" } } ]}

 Java代码在bulk里面有体现,这里就不赘述了。

10. Reindex API

 Reindex不尝试设置目标索引。它不复制源索引的设置。您应该在运行_reindex操作之前设置目标索引,包括设置映射、碎片计数、副本等。

 

# 复制源索引twitter到目标索引new_twitterPOST _reindex{
"source": { "index": "twitter" }, "dest": {
"index": "new_twitter" }}结果:{
"took" : 1626, "timed_out" : false, "total" : 16, "updated" : 0, "created" : 16, "deleted" : 0, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ]}# 查询GET /new_twitter/_search结果:{
"took" : 9, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 16, "max_score" : 1.0, "hits" : [ { "_index" : "new_twitter", "_type" : "t_doc", "_id" : "22", "_score" : 1.0, "_source" : { "user" : "Tony", "flag" : "1" } }, ... ] }}

 

为了避免出现冲突导致进程停止,指定:conflicts:proceed

POST _reindex{
"conflicts": "proceed", "source": { "index": "twitter" }, "dest": {
"index": "new_twitter", "op_type": "create" }}

 

还可以查询出指定的内容,然后送进目标索引

POST _reindex{
"source": { "index": "twitter", "type": "t_doc", "query": { "term": { "user": "kimchy" } } }, "dest": {
"index": "new_twitter" }}

 

和可以合并多个索引到目标索引

#合并两个索引,跳过冲突【conflicts】,只转移10000条数据【size】POST _reindex{
"conflicts": "proceed", "size": 10000, "source": { "index": ["twitter", "new_twitter"], "type": ["t_doc", "post"] }, "dest": {
"index": "all_together", "type": "all_doc" }}

 

还可以使用脚本、从远程服务器reindex、修改目标字段名称,请参考

Java

/**     * reIndex可用于将文档从一个或多个索引复制到目标索引     * DocWriteRequest.OpType.CREATE    跳过已有的文档     * DocWriteRequest.OpType.INDEX     已有相同id的会被覆盖     * @return     */    public static RestHighLevelClient reIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        ReindexRequest reindexRequest = new ReindexRequest()                .setSourceIndices("twitter","new_twitter")                .setDestIndex("all_together")                .setDestOpType(DocWriteRequest.OpType.INDEX.getLowercase())                .setDestDocType("all_doc")//                .setSize(10)    // copy的文档数//                .setScript(new Script(ScriptType.INLINE, "painless",//                        "if (ctx._source.user == 'kimchy') {ctx._source.likes++;}",//                        Collections.emptyMap()))  // 脚本                .setSourceBatchSize(500);   // 默认批量为1000,你可以自己设置批次获取的数量        reindexRequest.setConflicts("proceed"); // 默认情况下,版本冲突会中止_reindex进程(abort)        BulkByScrollResponse bulkResponse = client.reindex(reindexRequest, RequestOptions.DEFAULT);        TimeValue timeTaken = bulkResponse.getTook();        boolean timedOut = bulkResponse.isTimedOut();        long totalDocs = bulkResponse.getTotal();        long updatedDocs = bulkResponse.getUpdated();        long createdDocs = bulkResponse.getCreated();        long deletedDocs = bulkResponse.getDeleted();        long batches = bulkResponse.getBatches();        long noops = bulkResponse.getNoops();   // 跳过的文档数        long versionConflicts = bulkResponse.getVersionConflicts(); // 版本冲突的数量        long bulkRetries = bulkResponse.getBulkRetries();   // bulk重试次数        long searchRetries = bulkResponse.getSearchRetries();   // 搜索重试次数        System.out.println("花费时间:" + timeTaken + ",是否超时:" + timedOut + ",总文档数:" + totalDocs + ",更新数:" +                updatedDocs + ",创建数:" + createdDocs + ",删除数:" + deletedDocs + ",批量次数:" + batches + ",跳过数:" +                noops + ",冲突数:" + versionConflicts + ",bulk重试次数:" + bulkRetries + ",搜索重试次数:" + searchRetries);        List
searchFailures = bulkResponse.getSearchFailures(); // 搜索期间的故障 searchFailures.forEach(e -> { System.err.println("Cause:" + e.getReason().getMessage() + "Index:" + e.getIndex() + ",NodeId:" + e.getNodeId() + ",ShardId:" + e.getShardId()); }); List
bulkFailures = bulkResponse.getBulkFailures(); // 批量索引期间的故障 bulkFailures.forEach(e -> { System.err.println("Cause:" + e.getCause().getMessage() + "Index:" + e.getIndex() + ",Type:" + e.getType() + ",Id:" + e.getId()); }); return client; }

因为这两个索引内容一样,所以会出现 更新数:16,创建数:16

花费时间:1.6s,是否超时:false,总文档数:32,更新数:16,创建数:16,删除数:0,批量次数:1,跳过数:0,冲突数:0,bulk重试次数:0,搜索重试次数:0

查看目标索引(总文档数16

GET /all_together/_search结果:{
"took" : 4, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 16, "max_score" : 1.0, "hits" : [ { "_index" : "all_together", "_type" : "all_doc", "_id" : "22", "_score" : 1.0, "_source" : { "user" : "Tony", "flag" : "1" } }, ... ] }}

--

11. Query

HTTP请求

RequestBodySearch 示例

# sort--mode:min、max、sum、avg、median# sort--order:asc、desc# 过滤_source:如果要禁用,"_source": false# Doc格式化:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-docvalue-fields.html# 高亮参数:写在外面是全局的,写在field里面是局部的GET /_search{
"query" : { "term" : { "user" : "Tony" } }, "_source": [ "obj1.*", "obj2.*" ], "from" : 0, "size" : 10, "sort" : [ {
"price" : {"order" : "asc", "mode" : "avg"}} ], "script_fields" : {
"my_field1" : { "script" : { "lang": "painless", "source": "doc['flag'].value * params.factor", "params" : { "factor" : 2.0 } } } }, "docvalue_fields" : [ {
"field": "postDate", "format": "yyyy-MM-dd" } ], "highlight" : {
"order" : "score", "pre_tags" : ["
"], "post_tags" : ["
"], "fields" : { "_all" : {
}, "message" : {
"fragment_size" : 150, "number_of_fragments" : 3} } }}

 

QueryDSL

 **Match 与 Match Phrase【这里使用了ik分词器

# 准备测试数据PUT test{
"settings" : { "number_of_shards" : 1, "number_of_replicas" : 1 }, "mappings" : {
"msg" : { "properties" : { "message" : { "type" : "text","analyzer": "ik_max_word" } } } }}PUT test/msg/100{
"message" : "她过山车一般的跌宕人生,成了 2018 年我听过的最精彩、也最让人感叹唏嘘的真人真事。"}PUT test/msg/101{
"message" : "她就是我们今天的主人公,伊丽莎白·福尔摩斯(Elizabeth Holmes)。"}# match queryGET /_search{
"query": { "match" : { "message" : { "query" : "今天的主人公", "analyzer" : "ik_max_word" } } }}# Match Phrase Query 短语查询GET /_search{
"query": { "match_phrase" : { "message" : { "query" : "今天的主人公", "analyzer" : "ik_max_word" } } }}

 

执行match的结果:

执行match phrase的结果

 

分词器:

POST _analyze{
"analyzer": "ik_max_word", "text": "今天的主人公"}---{
"tokens" : [ { "token" : "今天", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 0 }, {
"token" : "的", "start_offset" : 2, "end_offset" : 3, "type" : "CN_CHAR", "position" : 1 }, {
"token" : "主人公", "start_offset" : 3, "end_offset" : 6, "type" : "CN_WORD", "position" : 2 }, {
"token" : "主人", "start_offset" : 3, "end_offset" : 5, "type" : "CN_WORD", "position" : 3 }, {
"token" : "公", "start_offset" : 5, "end_offset" : 6, "type" : "CN_CHAR", "position" : 4 } ]}

 

结论:match会查出包含所有token的结果,而matchPhrase则只会查询“今天的主人公”这一个词组

 **Match Phrase Prefix Query,短语前缀查询,顾名思义:以查询关键字为前缀的查询

# Match Phrase Prefix Query 短语前缀查询GET /_search{
"query": { "match_phrase_prefix" : { "message" : { "query" : "她就是", "analyzer" : "ik_max_word" } } }}---{
"took" : 9, "timed_out" : false, "_shards" : { "total" : 28, "successful" : 28, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 1, "max_score" : 3.2103658, "hits" : [ { "_index" : "test", "_type" : "msg", "_id" : "101", "_score" : 3.2103658, "_source" : { "message" : "她就是我们今天的主人公,伊丽莎白·福尔摩斯(Elizabeth Holmes)。" } } ] }}

 

**Query String Query

# 字符串查询 如果多个字段:"fields" : ["content", "name"] 代替default_fieldGET /_search{
"query": { "query_string" : { "default_field" : "message", "query" : "(过山车) OR (伊丽莎白)" } }}---{
"took" : 5, "timed_out" : false, "_shards" : { "total" : 28, "successful" : 28, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 2, "max_score" : 0.80259144, "hits" : [ { "_index" : "test", "_type" : "msg", "_id" : "101", "_score" : 0.80259144, "_source" : { "message" : "她就是我们今天的主人公,伊丽莎白·福尔摩斯(Elizabeth Holmes)。" } }, {
"_index" : "test", "_type" : "msg", "_id" : "100", "_score" : 0.6099695, "_source" : { "message" : "她过山车一般的跌宕人生,成了 2018 年我听过的最精彩、也最让人感叹唏嘘的真人真事。" } } ] }}

 


以下查询的字段类型都为keyword,适合精确查询

**TermQuery

# Term Query 适合关键字的查询,字段类型为keywordGET /_search{
"query": { "term": { "exact_value": "Quick Foxes!" } }}

 

**Terms Query

# Terms Query 对同一个字段匹配多个关键字GET /_search{
"query": { "terms" : { "user" : ["kimchy", "elasticsearch"]} }}

 

 **Range Query

# Range Query 范围查询【gt:大于,gte:大于等于,lt:小于,lte:小于等于】GET _search{
"query": { "range" : { "age" : { "gte" : 10, "lte" : 20, "boost" : 2.0 } } }}# Range Query 日期【y-年,M-月,w-周,d-日,h-小时,H-小时,m-分钟,s-秒。+1h:+1小时,-1d:-1天,/d:四舍五入到最近的日期,now:当前时间】比如:now = 2018-12-23 17:17:00 now/d = 2018-12-24 00:00:00GET _search{
"query": { "range" : { "date" : { "gte" : "now-1d/d", "lt" : "now/d" } } }}GET _search{
"query": { "range" : { "birthday" : { "gte": "01/01/2012", "lte": "2013", "format": "dd/MM/yyyy||yyyy" } } }}

 

**Exists Query

# Exist Query 返回在原始字段 message 中至少有一个非空值的文档GET /_search{
"query": { "exists" : { "field" : "message" } }}

 

 **Prefix Query

# Prefix Query 前缀查询GET /_search{
"query": { "prefix" : { "user" : "ki" } }}

 

 **Wildcard Query

# Wildcard Query 不建议以通配符开头,因为那样性能最低GET /_search{
"query": { "wildcard" : { "user" : "ki*y" } }}

 

 **Regexp Query

# Regexp Query 正则查询,你可以使用任何正则表达式,同样不建议以通配符开头GET /_search{
"query": { "regexp":{ "name.first": "s.*y" } }}

 

 **Fuzzy Query

# Fuzzy Query 模糊查询【与SQL的模糊查询不一样,更多信息请自行查阅资料】GET /_search{
"query": { "fuzzy" : { "user" : "ki" } }}

 

 **Type Query

# Type Query 查询type下的所有文档GET /_search{
"query": { "type" : { "value" : "t_doc" } }}

 

 **Ids Query

# Ids Query 根据id列表查询GET /_search{
"query": { "ids" : { "type" : "t_doc", "values" : ["1", "4", "100"] } }}

 


 

下面是复合查询

# bool查询【它有must、filter、should、must_not四个可选条件】POST _search{
"query": { "bool" : { "must" : { "term" : { "user" : "kimchy" } }, "filter": {
"term" : { "tag" : "tech" } }, "must_not" : {
"range" : { "age" : { "gte" : 10, "lte" : 20 } } }, "should" : [ {
"term" : { "tag" : "wow" } }, {
"term" : { "tag" : "elasticsearch" } } ], "minimum_should_match" : 1, "boost" : 1.0 } }}

下面是地理查询, 参见 19.2 geo_bounding_box查询 地图选点:

**地理边界查询【根据两个点确定的矩形,查询落在矩形内的坐标】

# 地理边界查询GET /china_index/_search{
"query": { "bool" : { "must" : { "match_all" : {
} }, "filter" : {
"geo_bounding_box" : { "location" : { "top_left" : "23.1706638271,113.0383300781", "bottom_right" : "22.9760953044,113.5025024414" } } } } }}

 

结果:

**地理半径查询【根据指定的坐标为中心,查询半径范围内的坐标】

# 地理半径查询GET /china_index/_search{
"query": { "bool" : { "must" : { "match_all" : {
} }, "filter" : {
"geo_distance" : { "distance" : "20km", "location" : { "lat" : 39.6733703918, "lon" : 116.4111328125 } } } } }}---{
"took" : 6, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 1, "max_score" : 1.0, "hits" : [ { "_index" : "china_index", "_type" : "city", "_id" : "150", "_score" : 1.0, "_source" : { "pName" : "北京市", "cName" : "大兴区", "location" : { "lat" : 39.72684, "lon" : 116.34159 } } } ] }}

 

**地理多边形查询【查找指定的坐标围成的多边形内的坐标】

# 地理多边形查询GET /china_index/_search{
"query": { "bool" : { "must" : { "match_all" : {
} }, "filter" : {
"geo_polygon" : { "location" : { "points" : [ "20.4270128143,110.2807617188", "19.6632802200,109.7094726563", "19.6839702359,110.8520507813" ] } } } } }}---{
"took" : 39, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 4, "max_score" : 1.0, "hits" : [ { "_index" : "china_index", "_type" : "city", "_id" : "1555", "_score" : 1.0, "_source" : { "pName" : "海南省", "cName" : "海口", "location" : { "lat" : 20.02, "lon" : 110.35 } } }, {
"_index" : "china_index", "_type" : "city", "_id" : "1556", "_score" : 1.0, "_source" : { "pName" : "海南省", "cName" : "琼山", "location" : { "lat" : 19.98, "lon" : 110.33 } } }, {
"_index" : "china_index", "_type" : "city", "_id" : "1558", "_score" : 1.0, "_source" : { "pName" : "海南省", "cName" : "定安", "location" : { "lat" : 19.68, "lon" : 110.31 } } }, {
"_index" : "china_index", "_type" : "city", "_id" : "1562", "_score" : 1.0, "_source" : { "pName" : "海南省", "cName" : "澄迈", "location" : { "lat" : 19.75, "lon" : 110.0 } } } ] }}

**地理形状查询 geo_shape【这个资料比较少,所以我重点研究了一下】

# 存储地理形状的索引# tree参数:geohash和quadtree,默认geohash# strategy参数:recursive和term,默认recursive【支持查询:INTERSECTS,DISJOINT,WITHIN,CONTAINS】# precision参数:精度,单位有in, inch, yd, yard, mi, miles, km, kilometers, m,meters, cm,centimeters, mm, millimeters# 形状类型解释                  |  GeoJSON Type   |      WKT Type  |      Elasticsearch Type# 单个地理坐标                     Point              POINT              point# 给出两个或多个点的任意一条线        LineString         LINESTRING        linestring# 闭合的多边形,第一个和最后一个点必须匹配  Polygon       POLYGON            polygon# 一系列未连接但可能相关的点         MultiPoint         MULTIPOINT         multipoint# 一系列独立的线                   MultiLineString    MULTILINESTRING    multilinestring# 一系列单独的多边形                MultiPolygon       MULTIPOLYGON       multipolygon# 类似于multi系列,但是多种类型不可以共存  GeometryCollection  GEOMETRYCOLLECTION  geometrycollection# 仅指定左上角和右下角的矩形         无                 BBOX                  envelope# 指定中心和半径的圆,默认单位是米    无                 无                     circlePUT china_shape_index{
"settings" : { "number_of_shards" : 1, "number_of_replicas" : 1 }, "mappings" : {
"info" : { "properties" : { "remark" : { "type" : "keyword" }, "location" : {
"type" : "geo_shape", "tree" : "geohash", "precision": "100m" } } } }}

 

添加不同类型的数据

# 注意,如果是数组[经度,纬度]# 添加一个点POST /china_shape_index/info{
"location" : { "type" : "point", "coordinates" : [109.1162109375,37.2653099556] }}# 添加一条线POST /china_shape_index/info{
"location" : { "type" : "linestring", "coordinates" : [[109.1162109375,37.2653099556], [117.6855468750,35.5322262277]] }}# 添加一个形状【我画了个三角形】POST /china_shape_index/info{
"location" : { "type" : "polygon", "coordinates" : [ [ [114.0380859375, 31.9148675033], [116.6748046875, 30.0690939644], [111.4453125000,29.7643773752], [114.0380859375, 31.9148675033] ] ] }}# 多个坐标POST /china_shape_index/info{
"location" : { "type" : "multipoint", "coordinates" : [ [111.4453125000,29.7643773752], [117.6855468750,35.5322262277] ] }}# 由leftTop和bottomRight围成的矩形POST /china_shape_index/info{
"location" : { "type" : "envelope", "coordinates" : [ [120.2783203125,25.2049411536], [122.2119140625,23.4430889311] ] }}# 圆形POST /china_shape_index/info{
"location" : { "type" : "circle", "coordinates" : [116.5429687500,39.7071866568], "radius" : "10km" }}

 

形状查询【这里与我们测试数据(以北京为中心画一个圆)相交了】

# 查询相交的形状。relation可选:intersects, disjoint, within, contains【相交,不相交,内部,包含】GET /china_shape_index/_search{
"query":{ "bool": { "must": { "match_all": {
} }, "filter": {
"geo_shape": { "location": { "shape": { "type": "envelope", "coordinates" : [[114.9169921875,40.5137991550], [118.6083984375,38.7883453551]] }, "relation": "intersects" } } } } }}---{
"took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 1, "max_score" : 1.0, "hits" : [ { "_index" : "china_shape_index", "_type" : "info", "_id" : "FbvH82cBOwlg01SCD5ab", "_score" : 1.0, "_source" : { "location" : { "type" : "circle", "coordinates" : [ 116.54296875, 39.7071866568 ], "radius" : "10km" } } } ] }}

..

Java【太多了,我只选择部分示例】

全文索引系列:matchQuery、matchAllQuery、matchPhraseQuery、matchPhrasePrefixQuery、multiMatchQuery、commonTermsQuery、queryStringQuery

Term系列:termQuery、termsQuery、rangeQuery、existsQuery、prefixQuery、wildcardQuery、regexpQuery、fuzzyQuery、typeQuery、idsQuery

地理系列:geoDistanceQuery、geoBoundingBoxQuery、geoPolygonQuery、geoShapeQuery

--

/**     * matchQuery      * 排序,高亮查询     * @return     * @throws IOException     */    public static RestHighLevelClient search() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        try {            SearchResponse search = client.search(new SearchRequest("test")                    .source(new SearchSourceBuilder()                            .query(QueryBuilders.matchQuery("message", "今天的主人公"))                            .sort("_score", SortOrder.DESC) // 根据分数倒序排序                            .from(0)    // 返回结果开始位置                            .size(5)    // 返回结果数量                            .timeout(TimeValue.timeValueSeconds(10))    // 超时                            .highlighter(new HighlightBuilder()                                    .field("message",200)                                    .preTags("
").postTags("
")) ), RequestOptions.DEFAULT); System.out.println("Hits:" + search.getHits().totalHits); search.getHits().forEach(e -> { System.out.println("分数:" + e.getScore() + ",结果:" + e.getSourceAsString()); Map
highlightFields = e.getHighlightFields(); for (String key : highlightFields.keySet()){ HighlightField field = highlightFields.get(key); System.out.println(key + ":" + field.fragments()[0]/* + "," + field.fragments().length*/); } }); } catch (ElasticsearchException e) { if(e.status() == RestStatus.NOT_FOUND){ // TODO System.out.println("Index Not Found-" + e.getIndex()); } } return client; }

 

输出:

Hits:2分数:3.421475,结果:{
"message":"她就是我们今天的主人公,伊丽莎白·福尔摩斯(Elizabeth Holmes)。"}message:她就是我们
今天
主人
,伊丽莎白·福尔摩斯(Elizabeth Holmes)。分数:0.26740497,结果:{
"message":"她过山车一般的跌宕人生,成了 2018 年我听过的最精彩、也最让人感叹唏嘘的真人真事。"}message:她过山车一般
跌宕人生,成了 2018 年我听过
最精彩、也最让人感叹唏嘘
真人真事。

 

 --

/**     * matchPhraseQuery     * 排序,高亮查询     * @return     * @throws IOException     */    public static RestHighLevelClient search() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        try {            SearchResponse search = client.search(new SearchRequest("test")                    .source(new SearchSourceBuilder()                            .query(QueryBuilders.matchPhraseQuery("message", "今天的主人公"))                            .sort("_score", SortOrder.DESC) // 根据分数倒序排序                            .from(0)    // 返回结果开始位置                            .size(5)    // 返回结果数量                            .timeout(TimeValue.timeValueSeconds(10))    // 超时                            .highlighter(new HighlightBuilder()                                    .field("message",200)                                    .preTags("
").postTags("
")) ), RequestOptions.DEFAULT); System.out.println("Hits:" + search.getHits().totalHits); search.getHits().forEach(e -> { System.out.println("分数:" + e.getScore() + ",结果:" + e.getSourceAsString()); Map
highlightFields = e.getHighlightFields(); for (String key : highlightFields.keySet()){ HighlightField field = highlightFields.get(key); System.out.println(key + ":" + field.fragments()[0]/* + "," + field.fragments().length*/); } }); } catch (ElasticsearchException e) { if(e.status() == RestStatus.NOT_FOUND){ // TODO System.out.println("Index Not Found-" + e.getIndex()); } } return client; }

 

 结果:

Hits:1分数:3.421475,结果:{
"message":"她就是我们今天的主人公,伊丽莎白·福尔摩斯(Elizabeth Holmes)。"}message:她就是我们
今天
主人
,伊丽莎白·福尔摩斯(Elizabeth Holmes)。

 

--

/**     * queryStringQuery     * 排序,高亮查询     * @return     * @throws IOException     */    public static RestHighLevelClient search() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        try {            SearchResponse search = client.search(new SearchRequest("test")                    .source(new SearchSourceBuilder()                            .query(QueryBuilders.queryStringQuery("今天的主人公").field("message"))                            .sort("_score", SortOrder.DESC) // 根据分数倒序排序                            .from(0)    // 返回结果开始位置                            .size(5)    // 返回结果数量                            .timeout(TimeValue.timeValueSeconds(10))    // 超时                            .highlighter(new HighlightBuilder()                                    .field("message",200)                                    .preTags("
").postTags("
")) ), RequestOptions.DEFAULT); System.out.println("Hits:" + search.getHits().totalHits); search.getHits().forEach(e -> { System.out.println("分数:" + e.getScore() + ",结果:" + e.getSourceAsString()); Map
highlightFields = e.getHighlightFields(); for (String key : highlightFields.keySet()){ HighlightField field = highlightFields.get(key); System.out.println(key + ":" + field.fragments()[0]/* + "," + field.fragments().length*/); } }); } catch (ElasticsearchException e) { if(e.status() == RestStatus.NOT_FOUND){ // TODO System.out.println("Index Not Found-" + e.getIndex()); } } return client; }

 

结果:

Hits:2分数:3.421475,结果:{
"message":"她就是我们今天的主人公,伊丽莎白·福尔摩斯(Elizabeth Holmes)。"}message:她就是我们
今天
主人
,伊丽莎白·福尔摩斯(Elizabeth Holmes)。分数:0.26740497,结果:{
"message":"她过山车一般的跌宕人生,成了 2018 年我听过的最精彩、也最让人感叹唏嘘的真人真事。"}message:她过山车一般
跌宕人生,成了 2018 年我听过
最精彩、也最让人感叹唏嘘
真人真事。

下面测试term系列

# 准备测试数据PUT users{
"settings" : { "number_of_shards" : 1, "number_of_replicas" : 1 }, "mappings" : {
"info" : { "properties" : { "username" : { "type" : "keyword" }, "address" : {
"type" : "text","analyzer": "ik_max_word" } } } }}PUT users/info/1{
"username" : "孙行者","address" : "软件产业基地1栋B座大堂","age": 15}PUT users/info/2{
"username" : "孙大圣","address" : "万达北路710号戈雅公寓105号商铺","age": 26}PUT users/info/3{
"username" : "西蒙·胡塞·德·拉·桑迪西玛·特里尼达·玻利瓦尔·帕拉修斯·伊·布兰科","address" : "滨河大道7009号","age": 7}PUT users/info/4{
"username" : "奥斯特洛夫斯基","address" : "光谷二路225号食堂","age": 30}PUT users/info/5{
"username" : "Brfxxccxxmnpcccclllmmnprxvclmnckssqlbb1111b","address" : "海淀紫竹院路甲2号商业05号","age": 18}# 查看GET /users/_search

--

/**     * termQuery     * rangeQuery     * prefixQuery     * wildcardQuery     * @return     * @throws IOException     */    public static RestHighLevelClient termSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        SearchRequest request = new SearchRequest("users");        String[] includeFields = new String[] {"username", "age"};        String[] excludeFields = new String[] {"addr*"};        request.source(new SearchSourceBuilder()                // 关键字查询                //.query(QueryBuilders.termsQuery("username", "奥斯特洛夫斯基"))                // 范围查询                //.query(QueryBuilders.rangeQuery("age").lt(20))                // 前缀查询                //.query(QueryBuilders.prefixQuery("username", "孙"))                // 通配符查询                .query(QueryBuilders.wildcardQuery("username", "西蒙*"))                .fetchSource(includeFields, excludeFields)  // 过滤源                .from(0)                .size(5)                .sort("age", SortOrder.ASC)        );        SearchResponse search = client.search(request, RequestOptions.DEFAULT);        System.out.println("Hits:" + search.getHits().totalHits);        search.getHits().forEach(e -> {            System.out.println(e.getSourceAsString());        });        return client;    }

结果:

Hits:1{
"age":7,"username":"西蒙·胡塞·德·拉·桑迪西玛·特里尼达·玻利瓦尔·帕拉修斯·伊·布兰科"}

 

 下面测试聚合查询 Aggregation

/**     * 聚合查询     * @return     * @throws IOException     */    public static RestHighLevelClient aggSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        SearchRequest request = new SearchRequest("users");        request.source(new SearchSourceBuilder()                .query(QueryBuilders.matchAllQuery())                .aggregation(AggregationBuilders.avg("ageAVG").field("age"))                .from(0)                .size(5)                .sort("age", SortOrder.ASC)        );        SearchResponse search = client.search(request, RequestOptions.DEFAULT);        System.out.println("Hits:" + search.getHits().totalHits);        search.getHits().forEach(e -> {            System.out.println(e.getSourceAsString());        });        Avg avg = search.getAggregations().get("ageAVG");        System.out.println("平均值:" + avg.getValue());        return client;    }

 

结果:

Hits:5{
"username":"西蒙·胡塞·德·拉·桑迪西玛·特里尼达·玻利瓦尔·帕拉修斯·伊·布兰科","address":"滨河大道7009号","age":7}{
"username":"孙行者","address":"软件产业基地1栋B座大堂","age":15}{
"username":"Brfxxccxxmnpcccclllmmnprxvclmnckssqlbb1111b","address":"海淀紫竹院路甲2号商业05号","age":18}{
"username":"孙大圣","address":"万达北路710号戈雅公寓105号商铺","age":26}{
"username":"奥斯特洛夫斯基","address":"光谷二路225号食堂","age":30}平均值:19.2

 

下面测试复合查询 bool

/**     * 复合查询     * @return     * @throws IOException     */    public static RestHighLevelClient boolSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        SearchRequest request = new SearchRequest("users");        request.source(new SearchSourceBuilder()                .query(QueryBuilders.boolQuery()                        .must(QueryBuilders.rangeQuery("age").gt(20))                        .mustNot(QueryBuilders.termQuery("username","孙大圣"))                )                .from(0)                .size(5)                .sort("age", SortOrder.ASC)        );        SearchResponse search = client.search(request, RequestOptions.DEFAULT);        System.out.println("Hits:" + search.getHits().totalHits);        search.getHits().forEach(e -> {            System.out.println(e.getSourceAsString());        });        return client;    }

结果:

Hits:1{
"username":"奥斯特洛夫斯基","address":"光谷二路225号食堂","age":30}

 

下面测试地理查询

--矩形

public static RestHighLevelClient geoSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        SearchRequest request = new SearchRequest("china_index");        request.source(new SearchSourceBuilder()                // 地理边界查询,设置字段名,top Left和bottom Right                .query(QueryBuilders.geoBoundingBoxQuery("location").setCorners(23.1706638271,113.0383300781,22.9760953044,113.5025024414))                .from(0)                .size(100)        );        SearchResponse search = client.search(request, RequestOptions.DEFAULT);        System.out.println("Hits:" + search.getHits().totalHits);        search.getHits().forEach(e -> {            System.out.println(e.getSourceAsString());        });        return client;    }

 

结果:

Hits:9{
"pName":"广东省","cName":"广州","location":{"lat":23.12908,"lon":113.26436}}{
"pName":"广东省","cName":"越秀","location":{"lat":23.12901,"lon":113.2668}}{
"pName":"广东省","cName":"荔湾","location":{"lat":23.12586,"lon":113.24428}}{
"pName":"广东省","cName":"海珠","location":{"lat":23.08331,"lon":113.3172}}{
"pName":"广东省","cName":"天河","location":{"lat":23.12463,"lon":113.36199}}{
"pName":"广东省","cName":"白云","location":{"lat":23.157032,"lon":113.273238}}{
"pName":"广东省","cName":"佛山","location":{"lat":23.02185,"lon":113.12192}}{
"pName":"广东省","cName":"禅城","location":{"lat":23.00944,"lon":113.12249}}{
"pName":"广东省","cName":"南海","location":{"lat":23.02882,"lon":113.14278}}

 

--圆形

public static RestHighLevelClient geoSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        SearchRequest request = new SearchRequest("china_index");        List
list = new ArrayList<>(); list.add(new GeoPoint(20.4270128143,110.2807617188)); list.add(new GeoPoint(19.6632802200,109.7094726563)); list.add(new GeoPoint(19.6839702359,110.8520507813)); request.source(new SearchSourceBuilder() // 地理半径查询,设置字段名,纬度,经度,距离,距离类型 .query(QueryBuilders.geoDistanceQuery("location").point(39.6733703918,116.4111328125).distance(50, DistanceUnit.KILOMETERS)) .from(0) .size(100) ); SearchResponse search = client.search(request, RequestOptions.DEFAULT); System.out.println("Hits:" + search.getHits().totalHits); search.getHits().forEach(e -> { System.out.println(e.getSourceAsString()); }); return client; }

 

 结果:

Hits:15{
"pName":"北京市","cName":"东城区","location":{"lat":39.92855,"lon":116.41637}}{
"pName":"北京市","cName":"西城区","location":{"lat":39.91231,"lon":116.36611}}{
"pName":"北京市","cName":"朝阳区","location":{"lat":39.927289,"lon":116.4498}}{
"pName":"北京市","cName":"丰台区","location":{"lat":39.85856,"lon":116.28616}}{
"pName":"北京市","cName":"石景山区","location":{"lat":39.90569,"lon":116.22299}}{
"pName":"北京市","cName":"海淀区","location":{"lat":39.95933,"lon":116.29845}}{
"pName":"北京市","cName":"通州区","location":{"lat":39.916195,"lon":116.662852}}{
"pName":"北京市","cName":"大兴区","location":{"lat":39.72684,"lon":116.34159}}{
"pName":"北京市","cName":"房山区","location":{"lat":39.74788,"lon":116.14294}}{
"pName":"北京市","cName":"门头沟区","location":{"lat":39.94048,"lon":116.10146}}{
"pName":"河北省","cName":"涿县","location":{"lat":39.48,"lon":115.98}}{
"pName":"河北省","cName":"廊坊","location":{"lat":39.53,"lon":116.7}}{
"pName":"河北省","cName":"安次","location":{"lat":39.52,"lon":116.69}}{
"pName":"河北省","cName":"固安","location":{"lat":39.44,"lon":116.29}}{
"pName":"河北省","cName":"永清","location":{"lat":39.32,"lon":116.48}}

 

 --多边形

public static RestHighLevelClient geoSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        SearchRequest request = new SearchRequest("china_index");        List
list = new ArrayList<>(); list.add(new GeoPoint(20.4270128143,110.2807617188)); list.add(new GeoPoint(19.6632802200,109.7094726563)); list.add(new GeoPoint(19.6839702359,110.8520507813)); request.source(new SearchSourceBuilder() // 地理形状查询,设置字段名,围成多边形状的坐标列表 .query(QueryBuilders.geoPolygonQuery("location", list)) .from(0) .size(100) ); SearchResponse search = client.search(request, RequestOptions.DEFAULT); System.out.println("Hits:" + search.getHits().totalHits); search.getHits().forEach(e -> { System.out.println(e.getSourceAsString()); }); return client; }

 

 结果:

Hits:4{
"pName":"海南省","cName":"海口","location":{"lat":20.02,"lon":110.35}}{
"pName":"海南省","cName":"琼山","location":{"lat":19.98,"lon":110.33}}{
"pName":"海南省","cName":"定安","location":{"lat":19.68,"lon":110.31}}{
"pName":"海南省","cName":"澄迈","location":{"lat":19.75,"lon":110.0}}

 

-- geo_shape查询

/**     * 地理形状查询     * https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-shape.html     * 已知Builder实现:CircleBuilder, EnvelopeBuilder, GeometryCollectionBuilder, LineStringBuilder, MultiLineStringBuilder, MultiPointBuilder, MultiPolygonBuilder, PointBuilder, PolygonBuilder     * @return     * @throws IOException     */    public static RestHighLevelClient geoShapeSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        SearchRequest request = new SearchRequest("china_shape_index");        request.source(new SearchSourceBuilder()                .query(QueryBuilders.geoShapeQuery("location",                        // 查询类型为envelope就用EnvelopeBuilder. topLeft,bottomRight. new Coordinate(经度,纬度)                        new EnvelopeBuilder(new Coordinate(114.9169921875,40.5137991550),new Coordinate(118.6083984375,38.7883453551)))                        .relation(ShapeRelation.INTERSECTS)                )                // ShapeBuilders已经过时,不推荐使用了                //.query(QueryBuilders.geoShapeQuery("location",ShapeBuilders.newEnvelope(new Coordinate(114.9169921875,40.5137991550),new Coordinate(118.6083984375,38.7883453551))))                .from(0)                .size(100)        );        SearchResponse search = client.search(request, RequestOptions.DEFAULT);        System.out.println("Hits:" + search.getHits().totalHits);        search.getHits().forEach(e -> {            System.out.println(e.getSourceAsString());        });        return client;    }

结果:

Hits:1{
"location":{"type":"circle","coordinates":[116.54296875,39.7071866568],"radius":"10km"}}

12. Search

**search scroll

/**     * scrollSearch     * @return     * @throws IOException     */    public static RestHighLevelClient scrollSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        // 设置超时        final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));        SearchRequest request = new SearchRequest("books");        request.source(new SearchSourceBuilder()                .query(QueryBuilders.matchAllQuery())                .sort("_id",SortOrder.ASC)                .size(500)) // 每批大小                .scroll(scroll);    // 设置scroll        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT); // 执行查询        String scrollId = searchResponse.getScrollId();        SearchHit[] hits = searchResponse.getHits().getHits();        while(hits != null && hits.length > 0) {            System.out.println("========Begin=======");            for (SearchHit hit : hits) {                System.out.println(hit.getSourceAsString());            }            System.out.println("========End=======");            System.out.println("Size:" + hits.length + ",Scroll:" + scrollId);            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId)                    .scroll(scroll);    // 设置SearchScrollRequest            searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);  // 拉取新的数据            scrollId = searchResponse.getScrollId();            hits = searchResponse.getHits().getHits();        };        // 当scroll超时时,Search Scroll API使用的搜索上下文将自动删除        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();        clearScrollRequest.addScrollId(scrollId);        ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);        boolean succeeded = clearScrollResponse.isSucceeded();        System.out.println("ClearScroll:" + succeeded);        return client;    }

 

结果:【一共2000条,省略了部分结果】

========Begin======={
"title":"title_1","user":"user_1"}{
"title":"title_10","user":"user_10"}{
"title":"title_100","user":"user_100"}{
"title":"title_1000","user":"user_1000"}...{
"title":"title_1448","user":"user_1448"}========End=======Size:500,Scroll:DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAM7QFndDcjZVejBqVHZHYVRIaDVhY054S0EAAAAAAADOzxZ3Q3I2VXowalR2R2FUSGg1YWNOeEtBAAAAAAAAztEWd0NyNlV6MGpUdkdhVEhoNWFjTnhLQQAAAAAAAM7SFndDcjZVejBqVHZHYVRIaDVhY054S0EAAAAAAADO0xZ3Q3I2VXowalR2R2FUSGg1YWNOeEtB========Begin=======...{
"title":"title_1899","user":"user_1899"}========End=======Size:500,Scroll:DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAM7QFndDcjZVejBqVHZHYVRIaDVhY054S0EAAAAAAADOzxZ3Q3I2VXowalR2R2FUSGg1YWNOeEtBAAAAAAAAztEWd0NyNlV6MGpUdkdhVEhoNWFjTnhLQQAAAAAAAM7SFndDcjZVejBqVHZHYVRIaDVhY054S0EAAAAAAADO0xZ3Q3I2VXowalR2R2FUSGg1YWNOeEtB========Begin======={
"title":"title_19","user":"user_19"}...{
"title":"title_548","user":"user_548"}========End=======Size:500,Scroll:DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAM7QFndDcjZVejBqVHZHYVRIaDVhY054S0EAAAAAAADOzxZ3Q3I2VXowalR2R2FUSGg1YWNOeEtBAAAAAAAAztEWd0NyNlV6MGpUdkdhVEhoNWFjTnhLQQAAAAAAAM7SFndDcjZVejBqVHZHYVRIaDVhY054S0EAAAAAAADO0xZ3Q3I2VXowalR2R2FUSGg1YWNOeEtB========Begin======={
"title":"title_549","user":"user_549"}...{
"title":"title_6","user":"user_6"}{
"title":"title_60","user":"user_60"}{
"title":"title_600","user":"user_600"}...{
"title":"title_699","user":"user_699"}{
"title":"title_7","user":"user_7"}{
"title":"title_70","user":"user_70"}{
"title":"title_700","user":"user_700"}...{
"title":"title_799","user":"user_799"}{
"title":"title_8","user":"user_8"}{
"title":"title_80","user":"user_80"}{
"title":"title_800","user":"user_800"}...{
"title":"title_899","user":"user_899"}{
"title":"title_9","user":"user_9"}{
"title":"title_90","user":"user_90"}{
"title":"title_900","user":"user_900"}...{
"title":"title_999","user":"user_999"}========End=======Size:500,Scroll:DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAM7QFndDcjZVejBqVHZHYVRIaDVhY054S0EAAAAAAADOzxZ3Q3I2VXowalR2R2FUSGg1YWNOeEtBAAAAAAAAztEWd0NyNlV6MGpUdkdhVEhoNWFjTnhLQQAAAAAAAM7SFndDcjZVejBqVHZHYVRIaDVhY054S0EAAAAAAADO0xZ3Q3I2VXowalR2R2FUSGg1YWNOeEtBClearScroll:true

 

**Multi-Search

HTTP请求

# 格式:一行header一行bodyGET users/_msearch{}{
"query": {"terms" : { "username" : ["孙行者", "孙大圣"]}}}{}{
"query": {"term" : { "username" : "Brfxxccxxmnpcccclllmmnprxvclmnckssqlbb1111b"}}}---{
"responses" : [ { "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 2, "max_score" : 1.0, "hits" : [ { "_index" : "users", "_type" : "info", "_id" : "1", "_score" : 1.0, "_source" : { "username" : "孙行者", "address" : "软件产业基地1栋B座大堂", "age" : 15 } }, {
"_index" : "users", "_type" : "info", "_id" : "2", "_score" : 1.0, "_source" : { "username" : "孙大圣", "address" : "万达北路710号戈雅公寓105号商铺", "age" : 26 } } ] }, "status" : 200 }, {
"took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : {
"total" : 1, "max_score" : 1.3862944, "hits" : [ { "_index" : "users", "_type" : "info", "_id" : "5", "_score" : 1.3862944, "_source" : { "username" : "Brfxxccxxmnpcccclllmmnprxvclmnckssqlbb1111b", "address" : "海淀紫竹院路甲2号商业05号", "age" : 18 } } ] }, "status" : 200 } ]}

 

Java

public static RestHighLevelClient multiSearch() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        MultiSearchRequest request = new MultiSearchRequest();        // 第一个查询        SearchRequest firstSearchRequest = new SearchRequest("users");        firstSearchRequest.source(new SearchSourceBuilder().query(QueryBuilders.termsQuery("username","孙大圣")));        request.add(firstSearchRequest);        // 第二个查询        SearchRequest secondSearchRequest = new SearchRequest("users");        secondSearchRequest.source(new SearchSourceBuilder().query(QueryBuilders.prefixQuery("username", "Brfxx")));        request.add(secondSearchRequest);        MultiSearchResponse msearch = client.msearch(request, RequestOptions.DEFAULT);        MultiSearchResponse.Item[] responses = msearch.getResponses();        for (MultiSearchResponse.Item i : responses){            System.out.println("========" + i.getResponse().status().name());            i.getResponse().getHits().forEach(e -> {                System.out.println(e.getSourceAsString());            });        }        return client;    }

 

结果:

========OK{
"username":"孙大圣","address":"万达北路710号戈雅公寓105号商铺","age":26}========OK{
"username":"Brfxxccxxmnpcccclllmmnprxvclmnckssqlbb1111b","address":"海淀紫竹院路甲2号商业05号","age":18}

 

13. Cluster

HTTP请求

GET _cluster/health---{
"cluster_name" : "my-elasticsearch", "status" : "yellow", "timed_out" : false, "number_of_nodes" : 1, "number_of_data_nodes" : 1, "active_primary_shards" : 15, "active_shards" : 15, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 14, "delayed_unassigned_shards" : 0, "number_of_pending_tasks" : 0, "number_of_in_flight_fetch" : 0, "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 51.724137931034484}

 获取集群状态

GET /_cluster/state---{
"cluster_name" : "my-elasticsearch", "compressed_size_in_bytes" : 14766, "cluster_uuid" : "QmDZ773JR_ip0AN6jEdWtA", "version" : 33, "state_uuid" : "l8WJu9BzTfGsIKba_gsodA", "master_node" : "wCr6Uz0jTvGaTHh5acNxKA", "blocks" : { }, "nodes" : {
"wCr6Uz0jTvGaTHh5acNxKA" : { "name" : "wCr6Uz0", "ephemeral_id" : "qFZoP0iWQDm3EWM3TDb_vg", "transport_address" : "127.0.0.1:9300", "attributes" : { "ml.machine_memory" : "8510087168", "xpack.installed" : "true", "ml.max_open_jobs" : "20", "ml.enabled" : "true" } } },...}
GET /_cluster/stats?human&prettyGET /_cluster/settings# 设置集群settings# 1. transient cluster settings# 2. persistent cluster settings# 3. settings in the elasticsearch.yml configuration file.PUT /_cluster/settings{
"persistent" : { "indices.recovery.max_bytes_per_sec" : "50mb" }}# explain索引【三个参数必须的】GET /_cluster/allocation/explain{
"index": "china_index", "shard": 0, "primary": true}# 节点统计数据GET /_nodes/statsGET /_nodes/nodeId1,nodeId2/stats# return just indicesGET /_nodes/stats/indices# return just os and processGET /_nodes/stats/os,process# return just process for node with IP address 10.0.0.1GET /_nodes/10.0.0.1/stats/process# 每个节点的实用信息GET _nodes/usageGET _nodes/nodeId1,nodeId2/usage

 

Java

/**     * 集群信息     * @return     */    public static RestHighLevelClient info() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        boolean ping = client.ping(RequestOptions.DEFAULT);        System.out.println("Ping:" + ping);        MainResponse info = client.info(RequestOptions.DEFAULT);        ClusterName clusterName = info.getClusterName();        String clusterUuid = info.getClusterUuid();        String nodeName = info.getNodeName();        Version version = info.getVersion();        Build build = info.getBuild();        System.out.println("集群名称:" + clusterName.value());        System.out.println("Uuid:" + clusterUuid);        System.out.println("节点名称:" + nodeName);        System.out.println("Version:" + version.toString());        System.out.println("Bulid:" + build.toString());        return client;    }

结果:

Ping:true集群名称:my-elasticsearchUuid:QmDZ773JR_ip0AN6jEdWtA节点名称:wCr6Uz0Version:6.5.0Bulid:[default][zip][816e6f6][2018-11-09T18:58:36.352602Z]

14. Indices

14.1 分词器

# 标准分词器GET _analyze{
"analyzer" : "standard", "text" : ["this is a test", "the second text"]}# IK分词器GET _analyze{
"analyzer" : "ik_smart", "text" : ["真好玩", "一个叫yado的博士找到他,希望buzzo和他的团伙去帮他散布一种叫做joy的毒品"]}

--

/**     * 分词器     * @return     * @throws IOException     */    public static RestHighLevelClient analyze() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        AnalyzeRequest request = new AnalyzeRequest();        request.text("真好玩", "一个叫yado的博士找到他,希望buzzo和他的团伙去帮他散布一种叫做joy的毒品");        request.analyzer("ik_smart");        AnalyzeResponse response = client.indices().analyze(request, RequestOptions.DEFAULT);        List
tokens = response.getTokens(); for(AnalyzeResponse.AnalyzeToken t : tokens){ int endOffset = t.getEndOffset(); int position = t.getPosition(); int positionLength = t.getPositionLength(); int startOffset = t.getStartOffset(); String term = t.getTerm(); String type = t.getType(); System.out.println("Start:" + startOffset + ",End:" + endOffset + ",Position:" + position + ",Length:" + positionLength + ",Term:" + term + ",Type:" + type); } return client; }

 

结果:

Start:0,End:3,Position:0,Length:1,Term:真好玩,Type:CN_WORDStart:4,End:6,Position:1,Length:1,Term:一个,Type:CN_WORDStart:6,End:7,Position:2,Length:1,Term:叫,Type:CN_CHARStart:7,End:11,Position:3,Length:1,Term:yado,Type:ENGLISHStart:11,End:12,Position:4,Length:1,Term:的,Type:CN_CHARStart:12,End:14,Position:5,Length:1,Term:博士,Type:CN_WORDStart:14,End:15,Position:6,Length:1,Term:找,Type:CN_CHARStart:15,End:17,Position:7,Length:1,Term:到他,Type:CN_WORDStart:18,End:20,Position:8,Length:1,Term:希望,Type:CN_WORDStart:20,End:25,Position:9,Length:1,Term:buzzo,Type:ENGLISHStart:25,End:27,Position:10,Length:1,Term:和他,Type:CN_WORDStart:27,End:28,Position:11,Length:1,Term:的,Type:CN_CHARStart:28,End:30,Position:12,Length:1,Term:团伙,Type:CN_WORDStart:30,End:31,Position:13,Length:1,Term:去,Type:CN_CHARStart:31,End:32,Position:14,Length:1,Term:帮,Type:CN_CHARStart:32,End:33,Position:15,Length:1,Term:他,Type:CN_CHARStart:33,End:35,Position:16,Length:1,Term:散布,Type:CN_WORDStart:35,End:37,Position:17,Length:1,Term:一种,Type:CN_WORDStart:37,End:39,Position:18,Length:1,Term:叫做,Type:CN_WORDStart:39,End:42,Position:19,Length:1,Term:joy,Type:ENGLISHStart:42,End:43,Position:20,Length:1,Term:的,Type:CN_CHARStart:43,End:45,Position:21,Length:1,Term:毒品,Type:CN_WORD

14.2 Create Index

创建索引限制

小写字母不能包含 \, /, *, ?, ", <, >, |, ` ` (space character), ,, #7.0之前的索引可能包含冒号(:),但是不赞成这样做,7.0+不支持这样做不能以-,_,+开头不能. or ..长度不能超过255字节

HTTP请求

# 创建索引PUT twitter{
"settings" : { "number_of_shards" : 3, "number_of_replicas" : 2 }, "mappings" : {
"my_doc" : { "properties" : { "field1" : { "type" : "text" } } } }}

 Java

public static RestHighLevelClient createIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        CreateIndexRequest request = new CreateIndexRequest("twitter");        request.settings(Settings.builder()                .put("index.number_of_shards", 3)                .put("index.number_of_replicas", 2))                // 设置mapping                //.mapping("t_doc", "field1","type=keyword,store=true")    // Object key-pairs                .mapping("t_doc", jsonBuilder()                .startObject()                    .startObject("t_doc")                        .startObject("properties")                            .startObject("msg")                                .field("type","text")                            .endObject()                        .endObject()                    .endObject()                .endObject())                // 别名                .alias(new Alias("my_index_alias"))                // 创建超时                .timeout(TimeValue.timeValueMinutes(2))                // 连接到主节点超时时间                .masterNodeTimeout(TimeValue.timeValueMinutes(1))                // 在创建索引返回响应之前等待的活动碎片副本的数量                .waitForActiveShards(2);        CreateIndexResponse indexResponse = client.indices().create(request, RequestOptions.DEFAULT);        boolean acknowledged = indexResponse.isAcknowledged();        boolean shardsAcknowledged = indexResponse.isShardsAcknowledged();        System.out.println(acknowledged);        return client;    }

14.3 Delete Index

# 删除索引DELETE /twitter

Java

public static RestHighLevelClient deleteIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        DeleteIndexRequest request = new DeleteIndexRequest();          // 使用_all或者通配符*可以删除所有索引。如果要禁用:action.destructive_requires_name=true        request.indices("twitter","it_book","car","school","story");        try {            AcknowledgedResponse acknowledgedResponse = client.indices().delete(request, RequestOptions.DEFAULT);            boolean acknowledged = acknowledgedResponse.isAcknowledged();            System.out.println(acknowledged);        } catch (ElasticsearchException exception) {            if (exception.status() == RestStatus.NOT_FOUND) {                System.err.println("Index Not Found");            }        }        return client;    }

14.4 Indices Exists

# 索引是否存在HEAD /china_index# Type是否存在HEAD /china_index/_mapping/city

Java

public static RestHighLevelClient existIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetIndexRequest request = new GetIndexRequest();        request.indices("china_index");        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);        System.out.println(exists);        return client;    }

14.5 Open Index

# 开启索引POST /twitter/_open

Java

public static RestHighLevelClient openIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        OpenIndexRequest request = new OpenIndexRequest("twitter");        request.timeout(TimeValue.timeValueMinutes(2));        OpenIndexResponse open = client.indices().open(request, RequestOptions.DEFAULT);        boolean acknowledged = open.isAcknowledged();        boolean shardsAcked = open.isShardsAcknowledged();        System.out.println(acknowledged);        return client;    }

14.6 Close Index

# 关闭索引POST /twitter/_close

Java

public static RestHighLevelClient closeIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        CloseIndexRequest request = new CloseIndexRequest("twitter");        request.timeout(TimeValue.timeValueMinutes(2));        AcknowledgedResponse closeIndexResponse = client.indices().close(request, RequestOptions.DEFAULT);        boolean acknowledged = closeIndexResponse.isAcknowledged();        System.out.println(acknowledged);        return client;    }

 

14.7 Shrink Index【压缩索引】

# 准备源索引PUT my_source_index{
"settings" : { "number_of_shards" : 4, "number_of_replicas" : 2, "index.blocks.write": true }}--{
"acknowledged" : true, "shards_acknowledged" : true, "index" : "my_source_index"}

压缩操作

POST my_source_index/_shrink/my_target_index?copy_settings=true{
"settings": { "index.number_of_shards": 1, "index.number_of_replicas": 1, "index.codec": "best_compression" }, "aliases": {
"my_search_indices": {
} }}--{
"acknowledged" : true, "shards_acknowledged" : true, "index" : "my_target_index"}

 

查看索引信息

GET my_source_index结果:{
"my_source_index" : { "aliases" : { }, "mappings" : {
}, "settings" : {
"index" : { "number_of_shards" : "4", "blocks" : { "write" : "true" }, "provided_name" : "my_source_index", "creation_date" : "1546589291669", "number_of_replicas" : "2", "uuid" : "tSYNLldWQNCOlR5NJGaH9g", "version" : {
"created" : "6050099" } } } }}---GET my_target_index结果:{
"my_target_index" : { "aliases" : { "my_search_indices" : { } }, "mappings" : {
}, "settings" : {
"index" : { "allocation" : { "max_retries" : "1" }, "shrink" : {
"source" : { "name" : "my_source_index", "uuid" : "tSYNLldWQNCOlR5NJGaH9g" } }, "blocks" : {
"write" : "true" }, "provided_name" : "my_target_index", "creation_date" : "1546589354014", "number_of_replicas" : "1", "uuid" : "F976xviGQ965JU9patwQnA", "version" : {
"created" : "6050099", "upgraded" : "6050099" }, "codec" : "best_compression", "routing" : {
"allocation" : { "initial_recovery" : { "_id" : "wCr6Uz0jTvGaTHh5acNxKA" } } }, "number_of_shards" : "1", "routing_partition_size" : "1", "resize" : {
"source" : { "name" : "my_source_index", "uuid" : "tSYNLldWQNCOlR5NJGaH9g" } } } } }}

 

Java

/**     * 压缩索引(将索引压缩为主分片数更少的新索引)     * 目标索引中请求的主碎片数量必须是源索引中碎片数量的一个因数。例如,有8个主碎片的索引可以压缩为4个、2个或1个主碎片;     * 或者有15个主碎片的索引可以压缩为5个、3个或1个主碎片。     * 过程:     *      首先,它创建一个新的目标索引,其定义与源索引相同,但是主碎片的数量较少     *      然后它将段从源索引硬链接到目标索引     *      最后,它将目标索引恢复为一个刚刚重新打开的closed index     * @return     */    public static RestHighLevelClient shrinkIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        ResizeRequest resizeRequest = new ResizeRequest("target_index", "source_index");        resizeRequest.getTargetIndexRequest()                .alias(new Alias("target_index_alias"))                .settings(Settings.builder()                        .put("index.number_of_shards", 2)                );        ResizeResponse resizeResponse = client.indices().shrink(resizeRequest, RequestOptions.DEFAULT);        boolean acknowledged = resizeResponse.isAcknowledged();        boolean shardsAcked = resizeResponse.isShardsAcknowledged();        System.out.println(acknowledged);        return client;    }

 

14.8 Split Index

准备数据

# index.number_of_routing_shards must be >= index.number_of_shardsPUT my_source_index2{
"settings" : { "number_of_shards" : 2, "index.number_of_routing_shards" : 8, "index.blocks.write": true }}--{
"acknowledged" : true, "shards_acknowledged" : true, "index" : "my_source_index2"}

拆分

# 拆分索引POST my_source_index2/_split/my_target_index2?copy_settings=true{
"settings": { "index.number_of_shards": 4 }, "aliases": {
"my_search_indices": {
} }}--{
"acknowledged" : true, "shards_acknowledged" : true, "index" : "my_target_index2"}

查看索引

GET my_source_index2结果:{
"my_source_index2" : { "aliases" : { }, "mappings" : {
}, "settings" : {
"index" : { "number_of_shards" : "2", "blocks" : { "write" : "true" }, "provided_name" : "my_source_index2", "creation_date" : "1546590226265", "number_of_replicas" : "1", "uuid" : "iuDENl3uQku0Ef6flu8S-Q", "version" : {
"created" : "6050099" } } } }}---GET my_target_index2结果:{
"my_target_index2" : { "aliases" : { "my_search_indices" : { } }, "mappings" : {
}, "settings" : {
"index" : { "number_of_shards" : "4", "routing_partition_size" : "1", "blocks" : { "write" : "true" }, "provided_name" : "my_target_index2", "resize" : {
"source" : { "name" : "my_source_index2", "uuid" : "iuDENl3uQku0Ef6flu8S-Q" } }, "creation_date" : "1546590255143", "number_of_replicas" : "1", "uuid" : "ZBnocs2bSker45kb2lXoRw", "version" : {
"created" : "6050099", "upgraded" : "6050099" } } } }}

Java

/**     * 拆分索引(每个原始的主碎片被拆分为新索引中的两个或多个主碎片)     * 重要:源索引必须在创建的时候指定number_of_routing_shards参数,以便将来有拆分的需要。在Elasticsearch 7.0这个前提被移除。     * 索引能被拆分的次数以及每个主分片能被拆分的个数取决于index.number_of_routing_shards参数的设置     * 过程:     *      首先,它创建一个新的目标索引,其定义与源索引相同,但是具有更多的主碎片     *      然后它将段从源索引硬链接到目标索引     *      创建了低级文件之后,所有文档将再次散列以删除属于不同碎片的文档     *      最后,它将目标索引恢复为一个刚刚重新打开的closed index     * @return     */    public static RestHighLevelClient  splitIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        ResizeRequest resizeRequest = new ResizeRequest("target_index", "source_index");        resizeRequest.timeout(TimeValue.timeValueSeconds(2))                .masterNodeTimeout(TimeValue.timeValueMinutes(1))                .setResizeType(ResizeType.SPLIT);  // 类型是拆分        resizeRequest.getTargetIndexRequest()                .alias(new Alias("target_index_alias"))                .settings(Settings.builder()                .put("index.number_of_shards", 4));        ResizeResponse resizeResponse = client.indices().split(resizeRequest, RequestOptions.DEFAULT);        boolean acknowledged = resizeResponse.isAcknowledged();        boolean shardsAcked = resizeResponse.isShardsAcknowledged();        return client;    }

14.9 Refresh

# 刷新索引【默认定期刷新】POST /kimchy,elasticsearch/_refreshPOST /_refresh

--

/**     * 刷新索引     * 默认情况下,刷新是定期调度的     * @return     */    public static RestHighLevelClient refreshIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        RefreshRequest refreshRequest = new RefreshRequest("index_1","index_2");                try {            RefreshResponse refresh = client.indices().refresh(refreshRequest, RequestOptions.DEFAULT);            int totalShards = refresh.getTotalShards();            int successfulShards = refresh.getSuccessfulShards();            int failedShards = refresh.getFailedShards();            DefaultShardOperationFailedException[] failures = refresh.getShardFailures();        } catch (ElasticsearchException exception) {            if (exception.status() == RestStatus.NOT_FOUND) {                // TODO            }        }        return client;    }

14.10 Flush

POST twitter/_flush

---

/**     * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-flush.html     * 索引的刷新进程通过将数据刷新到索引存储并清除内部事务日志,基本上将内存从索引中释放出来     * @return     * @throws IOException     */    public static RestHighLevelClient flushIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        FlushRequest requestMultiple = new FlushRequest("index1", "index2");        try {            FlushResponse flushResponse = client.indices().flush(requestMultiple, RequestOptions.DEFAULT);            int totalShards = flushResponse.getTotalShards();            int successfulShards = flushResponse.getSuccessfulShards();            int failedShards = flushResponse.getFailedShards();            DefaultShardOperationFailedException[] failures = flushResponse.getShardFailures();        } catch (ElasticsearchException exception) {            if (exception.status() == RestStatus.NOT_FOUND) {                // TODO            }        }        return client;    }

14.11 Clear Cache

# 清空缓存POST /twitter/_cache/clear

---

/**     * 清除索引的缓存     * @return     */    public static RestHighLevelClient clearCacheIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        ClearIndicesCacheRequest cacheRequest = new ClearIndicesCacheRequest("index1", "index2");        cacheRequest.queryCache(true);       // 查询        cacheRequest.fieldDataCache(true);   // 字段数据        cacheRequest.requestCache(true);     // 请求        cacheRequest.fields("field1", "field2", "field3");                try {            ClearIndicesCacheResponse clearCache = client.indices().clearCache(cacheRequest, RequestOptions.DEFAULT);            int totalShards = clearCache.getTotalShards();            int successfulShards = clearCache.getSuccessfulShards();            int failedShards = clearCache.getFailedShards();            DefaultShardOperationFailedException[] failures = clearCache.getShardFailures();        } catch (ElasticsearchException exception) {            if (exception.status() == RestStatus.NOT_FOUND) {                // TODO            }        }        return client;    }

14.12 Force Merge 

Http

# 合并POST /kimchy/_forcemerge?only_expunge_deletes=false&max_num_segments=100&flush=true# max_num_segments=1,所有的段都重写为一个新的POST /kimchy,elasticsearch/_forcemerge

 

Java

/**     * 合并一个或多个索引     * 此调用将阻塞,直到合并完成。如果http连接丢失,请求将在后台继续,任何新请求都将阻塞,直到前一个强制合并完成     * **强制合并只能对只读索引调用。对读写索引执行强制合并会导致产生非常大的段(每段大于5GB)     * https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-force-merge.html     * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html     * @return     */    public static RestHighLevelClient ForceMergeIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        ForceMergeRequest requestMultiple = new ForceMergeRequest("index1", "index2");        // 要合并的分片数。要完全合并索引,请将其设置为1        requestMultiple.maxNumSegments(1);        // 合并过程是否删除标记为删除的段。在Lucene中,一个文档不是从一个段中删除,而是标记为已删除。在段的合并过程中,将创建一个没有这些删除的新段。        // 此标志只允许合并具有删除的段。默认值为false        requestMultiple.onlyExpungeDeletes(true);        requestMultiple.flush(true);                try {            ForceMergeResponse forceMergeResponse = client.indices().forcemerge(requestMultiple, RequestOptions.DEFAULT);            int totalShards = forceMergeResponse.getTotalShards();            int successfulShards = forceMergeResponse.getSuccessfulShards();            int failedShards = forceMergeResponse.getFailedShards();            DefaultShardOperationFailedException[] failures = forceMergeResponse.getShardFailures();        } catch (ElasticsearchException exception) {            if (exception.status() == RestStatus.NOT_FOUND) {                // TODO            }        }        return client;    }

 

14.13 Put Mapping

 HTTP

# 增加一个不带type的索引PUT twitter {}# 增加typePUT twitter/_mapping/_doc {
"properties": { "email": { "type": "keyword" } }}

Java

/**     * 添加mapping(不能更新已存在的字段类型)     * @return     */    public static RestHighLevelClient putMapping() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        PutMappingRequest request = new PutMappingRequest("twitter");        request.type("_doc");        // 我更喜欢Object key-pairs 的形式        request.source("message","type=text","name","type=keyword");        request.timeout(TimeValue.timeValueMinutes(2));        request.masterNodeTimeout(TimeValue.timeValueMinutes(1));        AcknowledgedResponse putMappingResponse = client.indices().putMapping(request, RequestOptions.DEFAULT);        boolean acknowledged = putMappingResponse.isAcknowledged();        System.out.println(acknowledged);        return client;    }

14.14 Get Mappings

 HTTP

# 获取全部索引的Mapping,可以精确到typeGET /_all/_mapping/[Type]#获取指定索引的MappingGET /twitter/_mapping/[Type]# 例如:GET /china_index/_mapping...{
"china_index" : { "mappings" : { "city" : { "properties" : { "cName" : { "type" : "text" }, "location" : {
"type" : "geo_point" }, "pName" : {
"type" : "keyword" } } } } }}

Java

/**     * 获取mapping     * @return     * @throws IOException     */    public static RestHighLevelClient getMapping() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetMappingsRequest request = new GetMappingsRequest();        request.indices("china_index");        request.types("city");        request.masterNodeTimeout(TimeValue.timeValueMinutes(1));        GetMappingsResponse getMappingResponse = client.indices().getMapping(request, RequestOptions.DEFAULT);        getMappingResponse.getMappings().forEach(e -> {            String key = e.key;            ImmutableOpenMap
value = e.value; value.forEach(v -> { System.out.println(key + "|" + v.key + "|" + v.value.getSourceAsMap()); }); }); return client; }

结果:

china_index|city|{
properties={pName={type=keyword}, cName={
type=text}, location={
type=geo_point}}}

14.15 Get Field Mappings

 HTTP

# 查看具体字段的Mapping信息GET [索引]/_mapping/field/[field1,field2]GET china_index/_mapping/field/pName,location..{
"china_index" : { "mappings" : { "city" : { "pName" : { "full_name" : "pName", "mapping" : { "pName" : { "type" : "keyword" } } }, "location" : {
"full_name" : "location", "mapping" : { "location" : { "type" : "geo_point" } } } } } }}

Java

/**     * 获取指定字段的Mapping     * @return     * @throws IOException     */    public static RestHighLevelClient getFieldMappings() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetFieldMappingsRequest request = new GetFieldMappingsRequest();        request.indices("china_index");   // 可以多个索引        request.types("city");             // 多个类型        request.fields("pName","location");  // 多个字段        GetFieldMappingsResponse response = client.indices().getFieldMapping(request, RequestOptions.DEFAULT);        Map
>> mappings = response.mappings(); mappings.keySet().forEach(e -> { Map
> mapMap = mappings.get(e); mapMap.keySet().forEach(i -> { Map
metaDataMap = mapMap.get(i); metaDataMap.keySet().forEach(j -> { GetFieldMappingsResponse.FieldMappingMetaData fieldMappingMetaData = metaDataMap.get(j); System.out.println(e + "|" + i + "|" + j + "|" + fieldMappingMetaData.sourceAsMap()); }); }); }); return client; }

结果:

china_index|city|pName|{
pName={type=keyword}}china_index|city|location|{
location={type=geo_point}}

14.16 Index Aliases

 HTTP

# 添加别名POST /_aliases{
"actions" : [ { "remove" : { "index" : "test1", "alias" : "alias1" } }, {
"add" : { "index" : "test2", "alias" : "alias1" } } ]}# 例子POST /_aliases{
"actions" : [ { "add" : { "index" : "my_source_index", "alias" : "alias111" } }, {
"add" : { "index" : "my_source_index2", "alias" : "alias222" } } ]}...{
"acknowledged" : true}

 

Java

/**     * 添加别名,这个方法只是列出了一些情况,如果要运行请先根据实际情况修改     * @return     */    public static RestHighLevelClient indexAlias() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        IndicesAliasesRequest request = new IndicesAliasesRequest();        IndicesAliasesRequest.AliasActions aliasAction =                new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.ADD)                        .index("index1")                        .alias("alias1");        // 添加别名,并指定routing        IndicesAliasesRequest.AliasActions addIndicesAction =                new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.ADD)                        .indices("index1", "index2")                        .alias("alias2")                        .routing("my_routing");        // 移除别名        IndicesAliasesRequest.AliasActions removeAction =                new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.REMOVE)                        .index("index3")                        .alias("alias3");        // 删除索引        IndicesAliasesRequest.AliasActions removeIndexAction =                new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.REMOVE_INDEX)                        .index("index4");        request.addAliasAction(aliasAction);        AcknowledgedResponse indicesAliasesResponse =                client.indices().updateAliases(request, RequestOptions.DEFAULT);        boolean acknowledged = indicesAliasesResponse.isAcknowledged();        System.out.println(acknowledged);        return client;    }

 

14.17 Exists Alias

 HTTP

# 检查HEAD /my_source_index/_alias/alias111# 从所有索引里面找别名为2016的HEAD /_alias/2016# 还可以使用通配符HEAD /_alias/20*---存在的话200 - OK不存在404 - Not Found

Java

/**     * 判断别名是否存在     * @return     * @throws IOException     */    public static RestHighLevelClient aliasExist() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetAliasesRequest request = new GetAliasesRequest();        request.aliases("alias222");        request.indices("my_source_index2");//        GetAliasesRequest requestWithAlias = new GetAliasesRequest("alias1");   // 单个//        GetAliasesRequest requestWithAliases =//                new GetAliasesRequest(new String[]{"alias1", "alias2"});        // 多个        boolean exists = client.indices().existsAlias(request, RequestOptions.DEFAULT);        System.out.println(exists);        return client;    }

结果:true

14.18 Get Alias

HTTP

# 获取GET /my_source_index/_alias/alias111--{
"my_source_index" : { "aliases" : { "alias111" : { } } }}# 从所有索引里面找别名为alias222的GET /_alias/alias222--{
"my_source_index2" : { "aliases" : { "alias222" : { } } }}# 还可以使用通配符GET /_alias/20*# 显示索引的所有别名GET /my_source_index/_alias/*# 所有别名GET /_alias/*--{
"my_target_index2" : { "aliases" : { "my_search_indices" : { } } }, "my_source_index2" : {
"aliases" : { "alias222" : { } } }, ".kibana_1" : {
"aliases" : { ".kibana" : { } } }, "my_source_index" : {
"aliases" : { "alias111" : { } } }, "my_target_index" : {
"aliases" : { "my_search_indices" : { } } }}

 如果要删除

# 删除别名DELETE /my_source_index/_alias/alias111--{
"acknowledged" : true}

Java

/**     * 获取别名     * @return     * @throws IOException     */    public static RestHighLevelClient getAlias() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetAliasesRequest request = new GetAliasesRequest();        request.aliases("alias222");        request.indices("my_source_index2");//        GetAliasesRequest requestWithAlias = new GetAliasesRequest("alias1");//        GetAliasesRequest requestWithAliases =//                new GetAliasesRequest(new String[]{"alias1", "alias2"});        GetAliasesResponse response = client.indices().getAlias(request, RequestOptions.DEFAULT);        Map
> aliases = response.getAliases(); aliases.keySet().forEach(e -> { Set
aliasMetaData = aliases.get(e); System.out.println(e + ":" + aliasMetaData.toString()); }); return client; }

结果:

my_source_index2:[{  "alias222" : { }}]

 

14.19 Update Indices Settings

 HTTP

# 更新settingPUT /twitter/_settings{
"index" : { "number_of_replicas" : 2, "refresh_interval" : "1s" }}

 

Java

/**     * 更新setting     * @return     * @throws IOException     */    public static RestHighLevelClient updateSetting() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        // 更新单个        UpdateSettingsRequest request = new UpdateSettingsRequest("index1");        // 更新多个        //UpdateSettingsRequest requestMultiple =        //        new UpdateSettingsRequest("index1", "index2");        // 全部更新        //UpdateSettingsRequest requestAll = new UpdateSettingsRequest();        Settings settings =                Settings.builder()                        .put("index.number_of_replicas", 2)                        .build();        request.settings(settings);        AcknowledgedResponse updateSettingsResponse =                client.indices().putSettings(request, RequestOptions.DEFAULT);        boolean acknowledged = updateSettingsResponse.isAcknowledged();        System.out.println(acknowledged);        return client;    }

 

14.20 Get Settings

 HTTP

# 获取指定索引的settingsGET /twitter,kimchy/_settings# 获取全部settingsGET /_all/_settings

 

Java

/**     * 获取setting     * @return     * @throws IOException     */    public static RestHighLevelClient getSetting() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetSettingsRequest request = new GetSettingsRequest().indices("china_index");        GetSettingsResponse getSettingsResponse = client.indices().getSettings(request, RequestOptions.DEFAULT);        ImmutableOpenMap
settings = getSettingsResponse.getIndexToSettings(); settings.forEach(e -> { System.out.println(e.key); Settings value = e.value; value.keySet().forEach(k -> { System.out.println(k + ":" + value.get(k)); }); }); return client; }

 

结果:

china_indexindex.creation_date:1545294776325index.number_of_replicas:1index.number_of_shards:1index.provided_name:china_indexindex.uuid:LYn6XQ_sRZCazMtweW31ZAindex.version.created:6050099

 

14.21 Put Template & Get Templates

 

# 索引模板PUT _template/template_1{
"index_patterns": ["te*", "bar*"], "settings": { "number_of_shards": 1 }, "mappings": {
"my_doc": { "_source": { "enabled": false }, "properties": {
"host_name": { "type": "keyword" }, "created_at": {
"type": "date", "format": "EEE MMM dd HH:mm:ss Z YYYY" } } } }}# 删除模板DELETE /_template/template_1# 获取模板GET /_template/template_1# 获取所有模板GET /_template# 模板是否存在HEAD _template/template_1

14.22 Validate Query

public static RestHighLevelClient validateQuery() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        // ValidateQueryRequest需要一个或多个索引来验证查询。如果没有提供索引,则在所有索引上执行请求。        ValidateQueryRequest request = new ValidateQueryRequest("twitter");        QueryBuilder builder = QueryBuilders                .boolQuery()                .must(QueryBuilders.queryStringQuery("*:*"))                .filter(QueryBuilders.termQuery("user", "kimchy"));        request.query(builder);        request.allShards(true);// 默认情况下,请求只在一个随机选择的分片上执行        request.explain(true);        request.rewrite(true);        ValidateQueryResponse response = client.indices().validateQuery(request, RequestOptions.DEFAULT);        boolean isValid = response.isValid();        int totalShards = response.getTotalShards();        int successfulShards = response.getSuccessfulShards();        int failedShards = response.getFailedShards();        System.out.println("isValid:" + isValid + ",totalShards:" + totalShards + ",successfulShards:" + successfulShards + ",failedShards:" + failedShards);        if (failedShards > 0) {            for(DefaultShardOperationFailedException failure: response.getShardFailures()) {                String failedIndex = failure.index();                int shardId = failure.shardId();                String reason = failure.reason();                System.out.println("failedIndex:" + failedIndex + ",shardId:" + shardId + ",reason:" + reason);            }        }        for(QueryExplanation explanation: response.getQueryExplanation()) {            String explanationIndex = explanation.getIndex();            int shardId = explanation.getShard();            String explanationString = explanation.getExplanation();            System.out.println("explanationIndex:" + explanationIndex + ",shardId:" + shardId + ",explanationString:" + explanationString);        }        return client;    }

结果:

isValid:true,totalShards:5,successfulShards:5,failedShards:0explanationIndex:twitter,shardId:0,explanationString:ConstantScore(user:kimchy)explanationIndex:twitter,shardId:1,explanationString:ConstantScore(user:kimchy)explanationIndex:twitter,shardId:2,explanationString:ConstantScore(user:kimchy)explanationIndex:twitter,shardId:3,explanationString:ConstantScore(user:kimchy)explanationIndex:twitter,shardId:4,explanationString:ConstantScore(user:kimchy)

 

14.23 Get Index

 HTTP

# 获取所有索引信息GET /_all# 单个索引信息GET /twitter

 

Java

/**     * 获取索引详细信息     * @return     * @throws IOException     */    public static RestHighLevelClient getIndex() throws IOException {        RestHighLevelClient client = RestClientFactory.getInstance().getClient();        GetIndexRequest request = new GetIndexRequest().indices("_all");    // _all是关键字,列出所有索引信息。也可以是通配符*        GetIndexResponse indexResponse = client.indices().get(request, RequestOptions.DEFAULT);        // Mappings        ImmutableOpenMap
> mappings = indexResponse.getMappings(); mappings.forEach(e -> { String key = e.key; ImmutableOpenMap
map = e.value; System.out.println("Index:" + key); map.forEach(n -> { String type = n.key; MappingMetaData metaData = n.value; System.out.println(type + "|" + metaData.getSourceAsMap()); }); }); // Aliases System.out.println("**********************************"); ImmutableOpenMap
> aliases = indexResponse.getAliases(); aliases.forEach(e -> { String key = e.key; List
value = e.value; System.out.println("----" + key + "----"); value.forEach(a -> { System.out.println(a.alias()); }); }); // Settings System.out.println("**********************************"); ImmutableOpenMap
defaultSettings = indexResponse.defaultSettings(); defaultSettings.forEach(e -> { String key = e.key; Settings value = e.value; System.out.println("----" + key + "----"); value.keySet().forEach(k -> { System.out.println(k + ":" + value.get(k)); }); }); ImmutableOpenMap
settings = indexResponse.getSettings(); settings.forEach(e -> { String key = e.key; Settings value = e.value; System.out.println("----" + key + "----"); value.keySet().forEach(k -> { System.out.println(k + ":" + value.get(k)); }); }); return client; }

 

结果:

Index:china_shape_indexinfo|{
properties={location={precision=100.0m, type=geo_shape}, remark={
type=keyword}}}Index:china_indexcity|{
properties={pName={type=keyword}, cName={
type=text}, location={
type=geo_point}}}Index:booksjava|{
properties={title={type=text, fields={keyword={ignore_above=256, type=keyword}}}, user={
type=text, fields={keyword={ignore_above=256, type=keyword}}}}}Index:my_source_index2Index:my_target_index2Index:my_source_indexIndex:usersinfo|{
properties={address={analyzer=ik_max_word, type=text}, age={
type=long}, username={
type=keyword}}}Index:my_target_indexIndex:testmsg|{
properties={message={analyzer=ik_max_word, type=text}}}Index:.kibana_1doc|{
dynamic=strict, properties={server={properties={uuid={type=keyword}}}, visualization={
properties={savedSearchId={type=keyword}, description={
type=text}, uiStateJSON={
type=text}, title={
type=text}, version={
type=integer}, kibanaSavedObjectMeta={
properties={searchSourceJSON={type=text}}}, visState={
type=text}}}, graph-workspace={
properties={numVertices={type=integer}, description={
type=text}, numLinks={
type=integer}, title={
type=text}, version={
type=integer}, kibanaSavedObjectMeta={
properties={searchSourceJSON={type=text}}}, wsState={
type=text}}}, kql-telemetry={
properties={optInCount={type=long}, optOutCount={
type=long}}}, type={
type=keyword}, space={
properties={color={type=keyword}, _reserved={
type=boolean}, initials={
type=keyword}, name={
type=text, fields={keyword={ignore_above=2048, type=keyword}}}, description={
type=text}}}, url={
properties={accessCount={type=long}, accessDate={
type=date}, url={
type=text, fields={keyword={ignore_above=2048, type=keyword}}}, createDate={
type=date}}}, migrationVersion={
dynamic=true, type=object}, index-pattern={
properties={notExpandable={type=boolean}, fieldFormatMap={
type=text}, sourceFilters={
type=text}, typeMeta={
type=keyword}, timeFieldName={
type=keyword}, intervalName={
type=keyword}, fields={
type=text}, title={
type=text}, type={
type=keyword}}}, search={
properties={hits={type=integer}, columns={
type=keyword}, description={
type=text}, sort={
type=keyword}, title={
type=text}, version={
type=integer}, kibanaSavedObjectMeta={
properties={searchSourceJSON={type=text}}}}}, updated_at={
type=date}, canvas-workpad={
dynamic=false, properties={@created={type=date}, @timestamp={
type=date}, name={
type=text, fields={keyword={type=keyword}}}, id={
index=false, type=text}}}, namespace={
type=keyword}, telemetry={
properties={enabled={type=boolean}}}, timelion-sheet={
properties={hits={type=integer}, timelion_sheet={
type=text}, timelion_interval={
type=keyword}, timelion_columns={
type=integer}, timelion_other_interval={
type=keyword}, timelion_rows={
type=integer}, description={
type=text}, title={
type=text}, version={
type=integer}, kibanaSavedObjectMeta={
properties={searchSourceJSON={type=text}}}, timelion_chart_height={
type=integer}}}, config={
dynamic=true, properties={buildNum={type=keyword}}}, dashboard={
properties={hits={type=integer}, timeFrom={
type=keyword}, timeTo={
type=keyword}, refreshInterval={
properties={display={type=keyword}, section={
type=integer}, value={
type=integer}, pause={
type=boolean}}}, description={
type=text}, uiStateJSON={
type=text}, timeRestore={
type=boolean}, title={
type=text}, version={
type=integer}, kibanaSavedObjectMeta={
properties={searchSourceJSON={type=text}}}, optionsJSON={
type=text}, panelsJSON={
type=text}}}}}Index:twittert_doc|{
properties={msg={type=text, fields={keyword={ignore_above=256, type=keyword}}}, A={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, B={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, C={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, flag={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, D={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, color={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, updateUser={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, extMsg={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, counter={
type=long}, message={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, field={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, size={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, post_date={
type=date}, name={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, animal={
properties={cat={type=text, fields={keyword={ignore_above=256, type=keyword}}}, dog={
type=text, fields={keyword={ignore_above=256, type=keyword}}}}}, postDate={
type=date}, hate={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, favorite={
type=text, fields={keyword={ignore_above=256, type=keyword}}}, user={
type=text, fields={keyword={ignore_above=256, type=keyword}}}}}**********************************----china_shape_index--------.kibana_1----.kibana----china_index--------users--------my_source_index--------my_source_index2----alias222----my_target_index2----my_search_indices----my_target_index----my_search_indices----test--------twitter--------books----**********************************----my_target_index----index.allocation.max_retries:1index.blocks.write:trueindex.codec:best_compressionindex.creation_date:1546589354014index.number_of_replicas:1index.number_of_shards:1index.provided_name:my_target_indexindex.resize.source.name:my_source_indexindex.resize.source.uuid:tSYNLldWQNCOlR5NJGaH9gindex.routing.allocation.initial_recovery._id:wCr6Uz0jTvGaTHh5acNxKAindex.routing_partition_size:1index.shrink.source.name:my_source_indexindex.shrink.source.uuid:tSYNLldWQNCOlR5NJGaH9gindex.uuid:F976xviGQ965JU9patwQnAindex.version.created:6050099index.version.upgraded:6050099----twitter----index.creation_date:1545622508123index.number_of_replicas:1index.number_of_shards:5index.provided_name:twitterindex.uuid:TLReCXTSSe6tvI7yNveWgwindex.version.created:6050099----books----index.creation_date:1545708244767index.number_of_replicas:1index.number_of_shards:5index.provided_name:booksindex.uuid:leQWEGe8So6B10awTItCNgindex.version.created:6050099----users----index.creation_date:1545967628013index.number_of_replicas:1index.number_of_shards:1index.provided_name:usersindex.uuid:tyxNGtSsThOFDaTBBy7jKQindex.version.created:6050099----my_source_index----index.blocks.write:trueindex.creation_date:1546589291669index.number_of_replicas:2index.number_of_shards:4index.provided_name:my_source_indexindex.uuid:tSYNLldWQNCOlR5NJGaH9gindex.version.created:6050099----my_source_index2----index.blocks.write:trueindex.creation_date:1546590226265index.number_of_replicas:1index.number_of_shards:2index.provided_name:my_source_index2index.uuid:iuDENl3uQku0Ef6flu8S-Qindex.version.created:6050099----test----index.creation_date:1545791918478index.number_of_replicas:1index.number_of_shards:1index.provided_name:testindex.uuid:qF3UiIqHTLK_X7FSUUhlGwindex.version.created:6050099----china_shape_index----index.creation_date:1545981755548index.number_of_replicas:1index.number_of_shards:1index.provided_name:china_shape_indexindex.uuid:jhwyVqR0RQywyf3n7W0maQindex.version.created:6050099----china_index----index.creation_date:1545294776325index.number_of_replicas:1index.number_of_shards:1index.provided_name:china_indexindex.uuid:LYn6XQ_sRZCazMtweW31ZAindex.version.created:6050099----.kibana_1----index.auto_expand_replicas:0-1index.creation_date:1542353618696index.number_of_replicas:0index.number_of_shards:1index.provided_name:.kibana_1index.uuid:IvzG6JhgRJ-GgwTDWmmirQindex.version.created:6050099----my_target_index2----index.blocks.write:trueindex.creation_date:1546590255143index.number_of_replicas:1index.number_of_shards:4index.provided_name:my_target_index2index.resize.source.name:my_source_index2index.resize.source.uuid:iuDENl3uQku0Ef6flu8S-Qindex.routing_partition_size:1index.uuid:ZBnocs2bSker45kb2lXoRwindex.version.created:6050099index.version.upgraded:6050099Process finished with exit code 0

 

转载于:https://www.cnblogs.com/LUA123/p/10157386.html

你可能感兴趣的文章
iOS:自定义代码块{ }
查看>>
C# 远程链接指定计算机,获取该计算机的计算机名等信息
查看>>
[Flume][Kafka]Flume 与 Kakfa结合例子(Kakfa 作为flume 的sink 输出到 Kafka topic)
查看>>
OpenGL入门笔记(十一)
查看>>
kill命令
查看>>
python3爬虫(二)实战- 爬糗事百科
查看>>
windowsXP用户被禁用导致不能网站登录
查看>>
第 8 章 TokyoCabinet/Tyrant
查看>>
智慧城市逐步推进 未来城市建设突破口分析
查看>>
是谁在推动路由器智能连接功能的普及?
查看>>
物联网软件更新政策不明 智能冰箱也易沦为犯罪工具
查看>>
基于 SaaS 解决库存问题, Nextail 获 160 万美元融资
查看>>
中昌海运拟更名“中昌大数据股份有限公司”
查看>>
Windows 10新版可以更新了!这些新功能值得升级
查看>>
《微信公众平台开发最佳实践》——2.2 微信开发者中心
查看>>
《IPv6精髓(第2版)》——1.4 常见误解
查看>>
《精通ArcGIS Server 应用与开发》——2.2 ArcGIS Server架构
查看>>
《UNIX网络编程 卷1:套接字联网API(第3版)》——2.10 TCP端口号与并发服务器...
查看>>
Centrifugo —— 用 Golang 实现的实时消息通信平台
查看>>
《善用佳软:高效能人士的软件应用之道》一2.6 小工具之计算器
查看>>