ElasticSearch实战部分

http://172.31.10.101:5601/app/dev_tools#/console
https://juejin.cn/post/7194274971374321723
https://www.cnblogs.com/tanghaorong/p/16344391.html

java操作es的常用模式

目前,开发中使用java操作es,不管是框架集成,还是纯粹的使用es的api,主要通过下面两种方式:

  • rest-api,主流的像 RestHighLevelClient ;
  • 与springboot集成时的jpa操作,主要是 ElasticsearchRepository 相关的api;

上面两种模式的api在开发中都可以方便的使用,相比之下,RestHighLevelClient相关的api灵活性更高,而ElasticsearchRepository 底层做了较多的封装,学习和使用的成本更低,上手更快。

  • should 关键字表示查询中的条件可以匹配,但不是必须的,相当于逻辑上的 “OR”。
  • must 关键字表示查询中的条件必须全部匹配,相当于逻辑上的 “AND”。

kibana 报错 server is not ready yet 处理查看 kibana的日志
docker logs -t -f --tail 100 容器名
然后查看是否能够连接ES,172.31.0.1 使用docker的网口,/usr/local/docker_images_layer_dir/kibana/config 中配置的kibana.yml文件

解决ES-Head查询不到数据的问题https://blog.csdn.net/u013008898/article/details/111407995
先将文件拷贝出来,然后重新删除容器进行重新挂载
docker cp elasticsearch-head:/usr/src/app/_site/vendor.js /usr/local/docker_images_layer_dir/es-head/vendor.js

docker run -d
–name=elasticsearch-head
-p 9100:9100 -v /usr/local/docker_images_layer_dir/es-head/vendor.js:/usr/src/app/_site/vendor.js
-v /usr/local/docker_images_layer_dir/es-head/Gruntfile.js:/usr/src/app/Gruntfile.js
mobz/elasticsearch-head:5-alpine

然后强制刷新浏览器

QueryBuilder

在 Elasticsearch Java REST 客户端中,BoolQueryBuilder 是用于构建布尔查询的类,允许您组合多个查询条件,并指定逻辑关系,例如与(must)、或(should)、非(must_not)等。除了 BoolQueryBuilder,还有一些类似的构建器,用于构建不同类型的查询。以下是其中一些类似的类:

BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("field1", "value1"));
boolQuery.mustNot(QueryBuilders.termQuery("field2", "value2"));
boolQuery.should(QueryBuilders.termQuery("field3", "value3"));
MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("field", "value");
TermQueryBuilder termQuery = QueryBuilders.termQuery("field", "value");
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("field").gte("start_value").lte("end_value");
PrefixQueryBuilder prefixQuery = QueryBuilders.prefixQuery("field", "prefix_value");
WildcardQueryBuilder wildcardQuery = QueryBuilders.wildcardQuery("field", "value*");
MatchPhraseQueryBuilder matchPhraseQuery = QueryBuilders.matchPhraseQuery("field", "phrase to search");
NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("nested_field", 
QueryBuilders.matchQuery("nested_field.property", "value"), ScoreMode.None);

这些类似的构建器可以帮助您根据不同的查询需求构建相应的查询。您可以根据具体的业务逻辑选择合适的构建器来构建查询。

Elasticsearch REST API

Elasticsearch 提供了许多 API 端点,用于执行各种操作,包括索引、搜索、映射、集群状态等。以下是一些常用的 Elasticsearch REST API 命令示例:

PUT /index_name
DELETE /index_name
POST /index_name/_doc
{
  "field1": "value1",
  "field2": "value2"
}
GET /index_name/_doc/document_id
POST /index_name/_doc/document_id/_update
{
  "doc": {
    "field1": "new_value"
  }
}
DELETE /index_name/_doc/document_id
GET /index_name/_search
{
  "query": {
    "match": {
      "field": "value"
    }
  }
}
GET /index_name/_search
{
  "query": {
    "range": {
      "field": {
        "gte": "start_value",
        "lte": "end_value"
      }
    }
  }
}
GET /_analyze
{
  "text": "Your text to be analyzed"
}
GET /_cluster/health
GET /_cat/nodes
GET /index_name/_mapping
POST /index_name/_bulk
{ "index": { "_index": "index_name", "_id": "document_id" } }
{ "field1": "value1" }
{ "index": { "_index": "index_name", "_id": "document_id" } }
{ "field1": "value2" }

这只是一小部分 Elasticsearch 支持的 API 命令。您可以根据需要深入研究 Elasticsearch REST API,详细文档可以在 Elasticsearch 官方网站找到。请注意,为了执行这些命令,您需要使用适当的工具,如 cURL、Postman 或通过编程语言的 HTTP 客户端。

package com.imooc;

import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.bean.InfoObj;
import com.imooc.bean.ScoreTask;
import com.imooc.bean.User;
import com.imooc.entity.es.EsBlog;
import com.imooc.repository.EsBlogRepository;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetRequest;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.MaxAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;

@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class SpringbootBlogEsApplicationTests {

    @Autowired
    EsBlogRepository esBlogRepository;

    @Resource
    RestHighLevelClient esClient;

    public static ObjectMapper objectMapper = new ObjectMapper();


    @Test
    public void testRestHighLevelClient_write_doc() throws IOException {
        ScoreTask scoreTask = new ScoreTask();
        List<InfoObj> list = new ArrayList<>();
        list.add(new InfoObj("topicB", 1, 0, "", "{\"result\":50.0,\"collector\":\"TPS统计采集器\",\"colDataSourceId\":\"AIM-TPS\",\"dataSource\":\"CAP\",\"metricObjNm\":\"TPS\",\"toTS\":1111101010,\"metricObj\":\"TPS\",\"labelId\":\"CI0000004534_TPS\",\"configItemId\":\"CI0000001\"}\n"));
        list.add(new InfoObj("topicB", 1, 0, "", "{\"result\":50.0,\"collector\":\"TPS统计采集器\",\"colDataSourceId\":\"AIM-TPS\",\"dataSource\":\"CAP\",\"metricObjNm\":\"TPS\",\"toTS\":1111101010,\"metricObj\":\"TPS\",\"labelId\":\"CI0000004534_TPS\",\"configItemId\":\"CI0000001\"}\n"));
        list.add(new InfoObj("topicB", 1, 0, "", "{\"result\":50.0,\"collector\":\"TPS统计采集器\",\"colDataSourceId\":\"AIM-TPS\",\"dataSource\":\"CAP\",\"metricObjNm\":\"TPS\",\"toTS\":1111101010,\"metricObj\":\"TPS\",\"labelId\":\"CI0000004534_TPS\",\"configItemId\":\"CI0000002\"}\n"));
        list.add(new InfoObj("topicB", 1, 0, "", "{\"result\":50.0,\"collector\":\"TPS统计采集器\",\"colDataSourceId\":\"AIM-TPS\",\"dataSource\":\"CAP\",\"metricObjNm\":\"TPS\",\"toTS\":1111101010,\"metricObj\":\"TPS\",\"labelId\":\"CI0000004534_TPS\",\"configItemId\":\"CI0000003\"}\n"));
        scoreTask.setScoreObjectList(list);
        indexData(scoreTask,"score_task_index");
    }


    /**
     * 数据库_索引 测试
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_index() throws IOException {
        // 创建索引, 索引存在过期时间
//        CreateIndexRequest createIndexRequest = new CreateIndexRequest("user");
//        CreateIndexResponse indexResponse = esClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
//        boolean acknowledged = indexResponse.isAcknowledged();

        // 查询索引
        GetIndexRequest getIndexRequest = new GetIndexRequest("user");
        GetIndexResponse getIndexResponse = esClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
        System.out.println(getIndexResponse.getAliases());
        System.out.println(objectMapper.writeValueAsString(getIndexResponse.getMappings()));
        System.out.println(getIndexResponse.getSettings());

        GetIndexRequest request = new GetIndexRequest("user");
        boolean exists = esClient.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);


        // 删除索引
//        DeleteIndexRequest getDeleteIndexRequest = new DeleteIndexRequest("user");
//        AcknowledgedResponse delete = esClient.indices().delete(getDeleteIndexRequest, RequestOptions.DEFAULT);
//        System.out.println("索引状态:"+delete.isAcknowledged());
    }

    /**
     * http://172.31.10.101:5601/app/dev_tools#/console
     * 创建表_文档 document 测试
     * */
    @Test
    public void testRestHighLevelClient_document_add() throws IOException {
        IndexRequest indexRequest = new IndexRequest();
        indexRequest.index("user").id("100000001");
        User user = new User();
        user.setName("张飞90001飞飞66");
        user.setSex("男");
        user.setAge(22);
        user.setSalary(10000);
        String userData = objectMapper.writeValueAsString(user);
        indexRequest.source(userData, XContentType.JSON);
        IndexResponse indexResponse = esClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("创建索引状态:"+indexResponse.status().getStatus());
        System.out.println("创建索引结果:"+indexResponse.getResult());
        System.out.println("创建索引结果:"+indexResponse.getResult().toString());

    }

    /**
     * http://172.31.10.101:5601/app/dev_tools#/console
     * 更新文档 document 测试
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_document_update() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index("user").id("10086");
        updateRequest.doc(XContentType.JSON,"name","王雄宇");
        UpdateResponse updateResponse = esClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println("更新索引状态:"+updateResponse.status());
    }

    /**
     * http://172.31.10.101:5601/app/dev_tools#/console
     * 删除文档 document 测试
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_document_delete() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest();
        deleteRequest.index("user").id("10086");
        DeleteResponse deleteResponse = esClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println("删除索引状态:"+deleteResponse.status());
    }

    /**
     * 批量写文档 document 测试
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_document_batch_save() throws IOException {

        List<String> list  = new ArrayList<>();
        list.add("张飞");
        list.add("关羽");
        list.add("赵云");
        list.add("黄忠");
        list.add("马超");
        list.add("吕布");
        list.add("典韦");
        list.add("乐进");
        list.add("卧龙");
        list.add("周瑜");

        // 创建List集合
        List<String> beautyList = new ArrayList<>();

        // 将三国演义中的美女添加到List集合中
        beautyList.add("貂蝉");
        beautyList.add("王异");
        beautyList.add("甄氏");
        beautyList.add("黄承儿");
        beautyList.add("王异");
        beautyList.add("孙尚香");
        beautyList.add("小乔");
        beautyList.add("大乔");
        beautyList.add("西施");
        beautyList.add("昭君");


        BulkRequest bulkRequest = new BulkRequest();
        for (int i = 1; i <= 10; i++) {
            IndexRequest indexRequest = new IndexRequest();
            indexRequest.index("user").id(String.valueOf(i));
            User user = new User();
            user.setName(beautyList.get(i-1));
            user.setSex("女");
            user.setAge(18);
            user.setSalary(10000*i+10000);
            String userData = objectMapper.writeValueAsString(user);
            indexRequest.source(userData, XContentType.JSON);
            bulkRequest.add(indexRequest);
        }

        for (int i = 1; i <= 10; i++) {
            IndexRequest indexRequest = new IndexRequest();
            indexRequest.index("user").id(String.valueOf(12+i));
            User user = new User();
            user.setName(list.get(i-1));
            user.setSex("男");
            user.setAge(20+i);
            user.setSalary(10000*i);
            String userData = objectMapper.writeValueAsString(user);
            indexRequest.source(userData, XContentType.JSON);
            bulkRequest.add(indexRequest);
        }
        BulkResponse bulkResponse = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulkResponse.status());
        System.out.println(objectMapper.writeValueAsString(bulkResponse.getItems()));
    }

    /**
     * 批量删除 document 测试
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_document_batch_delete() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        for (int i = 1; i <= 10; i++) {
            DeleteRequest deleteRequest = new DeleteRequest();
            deleteRequest.index("user").id(String.valueOf(i));
            bulkRequest.add(deleteRequest);
        }
        BulkResponse bulkResponse = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulkResponse.status());
        System.out.println(objectMapper.writeValueAsString(bulkResponse.getItems()));
    }

    /**
     *
     * 查询某个索引下所有的数据
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_all() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");

        // size 控制返回的条数,默认返回10条数据
        SearchSourceBuilder query = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).size(50);
        searchRequest.source(query);

        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits().value);

        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

    }

    /**
     * 批量查询多条数据,针对那种需要一次性查出多条数据的场景可以考虑使用
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_more() throws IOException {
        MultiGetRequest multiGetRequest = new MultiGetRequest();
        multiGetRequest.add(new MultiGetRequest.Item("user", "10086"));
        multiGetRequest.add(new MultiGetRequest.Item("user", "2"));

        MultiGetResponse getItemResponses = esClient.mget(multiGetRequest, RequestOptions.DEFAULT);
        Iterator<MultiGetItemResponse> iterator = getItemResponses.iterator();
        while (iterator.hasNext()) {
            MultiGetItemResponse item = iterator.next();
            System.out.println(item.getResponse().getSourceAsString());
        }
    }

    /**
     * 根据条件精确查询,根据性别查询,有点类似于mysql 中的 where sex='女' 这样的效果
     *
     * 总的来说,TermQueryBuilder 是用于构建特定字段上的精确匹配查询的查询构建器,
     * 而 SearchSourceBuilder 是用于构建完整的搜索查询的查询源构建器,
     * 它可以包含多个不同类型的查询构建器以及其他搜索参数,用于构建更为复杂的搜索查询。
     *
     * TermQueryBuilder:
     *      TermQueryBuilder 是用于构建特定字段上的精确匹配查询的查询构建器。它匹配指定字段上的确切值。
     *      例如,你可以使用 TermQueryBuilder 来构建一个搜索查询,要求某个字段的值必须与指定的值完全匹配。
     *      与其他类型的查询构建器相比,TermQueryBuilder 更适合于精确匹配,例如在进行关键字或标识符搜索时使用。
     *
     * SearchSourceBuilder:
     *      SearchSourceBuilder 是用于构建完整的搜索查询的查询源构建器。它允许你设置各种查询条件、过滤器、排序方式、聚合等。
     *      SearchSourceBuilder 可以包含多个不同类型的查询构建器,例如 TermQueryBuilder、MatchQueryBuilder、RangeQueryBuilder 等
     *      通过 SearchSourceBuilder,你可以构建更为复杂的查询,包括多个条件的组合、排序、分页等功能。
     *      一般来说,SearchSourceBuilder 是构建整个搜索请求的核心,它允许你在一个对象中组合和设置所有的查询参数。
     *
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("sex", "女");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(termQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();

        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     * 分页查询 from + size的使用 。类似于MySQL分页查询
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_page() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.matchAllQuery())
                .from(1).size(3);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     * 排序查询,查询结果按照某个字段进行排序,按年龄 倒序
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_sort() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.matchAllQuery())
                .sort("age", SortOrder.DESC);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());

        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     * 过滤查询,查询结果过滤某些字段
     * {"name":"周瑜","sex":"男","age":30,"salary":100000}
     * 只查询name 和 sex
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_filter() throws IOException {
        String[] includes = {"name", "sex"};
        String[] excludes = {"age"};
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.matchAllQuery())
                .fetchSource(includes,excludes);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }



    /**
     * es可以像mysql那样组合多个条件进行查询,考察对BoolQuery的使用,如下:查询性别为难男,年龄在35到45之间的用户;
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_more_filter() throws IOException {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("sex", "男"))
                .must(QueryBuilders.rangeQuery("age").gte(25).lte(40));
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
                .query(boolQueryBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     * 查询范围查询,RangeQueryBuilder 范围查询
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_range() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 范围查询 , >= <=  大于小于 都是包含关系
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").gte(25).lte(29);
        sourceBuilder.query(rangeQueryBuilder);
        searchRequest.source(sourceBuilder);

        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     * 模糊查询,使用 FuzzyQueryBuilder
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_Fuzzy() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // ZERO、ONE 和 TWO 是指定模糊搜索级别的常量,分别表示没有模糊匹配、允许一个编辑距离的模糊匹配和允许两个编辑距离的模糊匹配。
        // AUTO 常量表示自动模糊搜索,Elasticsearch 将根据搜索字符串的长度自动确定模糊搜索的级别。
        FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name", "张飞").fuzziness(Fuzziness.ONE);
        sourceBuilder.query(fuzzyQueryBuilder);
        searchRequest.source(sourceBuilder);


        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());

        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     * 高亮查询,带颜色的查询, 高亮查询需要查看配置是否打开,等一些操作才能看到
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_high_query() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("age", "28");
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .field("name")
                .preTags("<font color='red'>")
                .postTags("</font>");
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.highlighter(highlightBuilder);


        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
            System.out.println(hit.getHighlightFields().get("name").fragments()[0].string());
        }

        esClient.close();
    }

    /**
     * 多字段查询,使用 MultiMatchQueryBuilder
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_multi_match() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("张飞", "name", "sex");
        //表示从多个字段中匹配某个关键字
        multiMatchQueryBuilder.operator(Operator.OR);
        sourceBuilder.query(multiMatchQueryBuilder);
        searchRequest.source(sourceBuilder);

        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());

        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

    }


    /**
     * 聚合查询
     * 使用了一个最大值聚合(Max Aggregation),它计算了 "age" 字段的最大值。在实际应用中,您可以根据具体的需求构建各种不同类型的聚合,例如平均值、求和、统计等,以便对数据进行深入分析和洞察。
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_aggregated() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        MaxAggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");
        sourceBuilder.aggregation(aggregationBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);

        // {"maxAge":{"name":"maxAge","value":30.0,"valueAsString":"30.0","type":"max","metaData":null,"fragment":true}}
        System.out.println(objectMapper.writeValueAsString(searchResponse.getAggregations().getAsMap()));
        System.out.println(objectMapper.writeValueAsString(searchResponse.getHits().getHits()));
        System.out.println(searchResponse.getHits().getTotalHits());
        SearchHits hits = searchResponse.getHits();

        for (SearchHit searchHit : hits){
            System.out.println(searchHit.getSourceAsString());
        }

    }


    /**
     * 分组查询
     * @throws IOException
     */
    @Test
    public void testRestHighLevelClient_search_index_groupBy() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.aggregation(AggregationBuilders.terms("ageGroup").field("age"));
        searchRequest.source(sourceBuilder);

        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(objectMapper.writeValueAsString(searchResponse.getAggregations().getAsMap()));
        System.out.println(objectMapper.writeValueAsString(searchResponse.getHits().getHits()));
        System.out.println(searchResponse.getHits().getTotalHits());
        SearchHits hits = searchResponse.getHits();
        for (SearchHit searchHit : hits){
            System.out.println(searchHit.getSourceAsString());
        }
        esClient.close();

    }

    public void indexData(ScoreTask scoreTask, String indexName) throws IOException {
        if (scoreTask == null || CollectionUtils.isEmpty(scoreTask.getScoreObjectList())) {
            log.info("scoreTask is null or scoreObjectList is empty  index {}", indexName);
            return;
        }
        indexName = StringUtils.isEmpty(indexName) ? "unknown_" + System.currentTimeMillis() : indexName.toLowerCase(Locale.ROOT);
        if (!indexExists(indexName)) {
            log.info("索引不存在,创建索引:{}",indexName);
            createIndex(indexName);
        }

        int i = 1;
        BulkRequest bulkRequest = new BulkRequest();
        List scoreObjectList = scoreTask.getScoreObjectList();
        for (Object scoreObject : scoreObjectList) {
            JSONObject jsonObject = new JSONObject(scoreObject);
            String id = jsonObject.getStr("configItemId");
            String asString = objectMapper.writeValueAsString(scoreObject);
            IndexRequest indexRequest = new IndexRequest()
                    .index(indexName)
                    .id("CI0000029"+i)
                    .source(asString, XContentType.JSON)
                    .setPipeline("timestamp-pipeline");


            bulkRequest.add(indexRequest);
            i++;
        }
        BulkResponse responses = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        log.info("indexData success  index {} response {}", indexName,responses.status().getStatus());
    }

    public boolean indexExists(String indexName) {
        GetIndexRequest request = new GetIndexRequest(indexName);
        try {
            return esClient.indices().exists(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("indexExists error ", e);
        }
        return false;
    }

    public void createIndex(String indexName) {
        CreateIndexRequest request = new CreateIndexRequest(indexName);
        try {
            request.settings(Settings.builder()
                    .put("index.number_of_shards",3)
                    .put("index.number_of_replicas",1)
                    .build());
            CreateIndexResponse indexResponse = esClient.indices().create(request, RequestOptions.DEFAULT);
            if (indexResponse.isAcknowledged()) {
                log.info("createIndex success {}", indexName);
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("createIndex error ", e);
        }

    }






    @Test
    public void testEs() {
        Iterable<EsBlog> all = esBlogRepository.findAll();
        Iterator<EsBlog> esBlogIterator = all.iterator();
        for (EsBlog esBlog : all) {
            System.out.println(esBlog.toString());
        }
        EsBlog esBlog = esBlogIterator.next();

        log.info("【es集成springboot】esBlog={}",esBlog);
    }


    @Test
    public void insertSampleData() {
        for (int i = 100; i <= 110; i++) {
            EsBlog esBlog = new EsBlog();
            esBlog.setId(i);
            esBlog.setTitle("你好年轻人");
            esBlog.setAuthor("Author " + i);
            esBlog.setContent("你好年轻人哈哈哈");
            esBlog.setCreateTime(new Date());
            esBlog.setUpdateTime(new Date());
            esBlog.setLastDatetime(System.nanoTime());
            esBlog.setThirdDatetime(LocalDateTime.now());

            // 使用 SimpleDateFormat 将字符串转换为 Date
//            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            try {
//                Date createTime = dateFormat.parse("2023-01-01 12:00:00");
//                esBlog.setCreateTime(createTime);
//                esBlog.setUpdateTime(createTime);
//            } catch (ParseException e) {
//                e.printStackTrace();
//            }

            //             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //            LocalDateTime createTime = LocalDateTime.parse("2023-01-01 12:00:00", formatter);
            //
            //            esBlog.setCreateTime(createTime);
            //            esBlog.setUpdateTime(createTime);
            esBlogRepository.save(esBlog);

        }
    }



}

  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值