ES客户端文档操作

1.引入依赖

<!--spring-boot-data-es-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

在导入依赖后需要在yml文件中配置es的地址

spring:
  elasticsearch:
    rest:
      uris: http://101.35.161.133:9200

使用java文档操作es,可以使用以下对象

  • ElasticsearchOperations
  • RestHighLevelClient **推荐

2.ElasticsearchOperations使用

2.1创建索引对象

package com.example.demo.entity;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

/**
 * @Document: 将这个类对象转为 es 中一条文档进行录入
 *      indexName: 用来指定文档的索引名称
 *      createIndex: 用来指定是否创建索引
 */
@Data
@Document(indexName = "students",createIndex = true)
public class Student {
    @Id//用来将放入对象 id 值 作为文档_id 进行映射
    private Long id;
    @Field(type = FieldType.Keyword)//不可以用作分词
    private String name;
    @Field(type = FieldType.Keyword)
    private String sex;
    @Field(type = FieldType.Integer)
    private Integer age;
    @Field(type = FieldType.Text)//可以用做分词
    private String desc;
}

创建测试类,自动注入ElasticsearchOperations对象,执行save操作

@SpringBootTest
public class StudentTest {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Test
    public void createData(){
        Student student=new Student();
        student.setId(1L);
        student.setName("张三");
        student.setSex("男");
        student.setAge(18);
        student.setDesc("大家好我是张三,我是一名画家");
        elasticsearchOperations.save(student);
    }
}

查看es

es 模板创建 es在项目中如何使用_elasticsearch

2.2查询一条数据

@Test
    public void findOne(){
        Student student = elasticsearchOperations.get("1", Student.class);
        System.out.println("student = " + student);
    }

es 模板创建 es在项目中如何使用_System_02

2.3查询所有

@Test
    public void findAll() throws JsonProcessingException {
        SearchHits<Student> search = elasticsearchOperations.search(Query.findAll(), Student.class);
        System.out.println("search.getMaxScore() = " + search.getMaxScore());
        System.out.println("search.getTotalHits() = " + search.getTotalHits());
        for (SearchHit<Student> studentSearchHit : search) {
            System.out.println(new ObjectMapper().writeValueAsString(studentSearchHit.getContent()));
        }
    }

es 模板创建 es在项目中如何使用_System_03

2.4删除一条文档

@Test
    public void deleteOne(){
        Student student=new Student();
        student.setId(1L);
        elasticsearchOperations.delete(student);
    }

2.5删除所有

@Test
    public void deleteAll(){
        elasticsearchOperations.delete(Query.findAll(), Student.class);
    }

3.RestHighLevelClient 的使用

RestHighLevelClient 的使用和kibana的使用基本相同,所以是推荐的使用方式。

3.1RestHighLevelClient 的基本操作

3.1.1创建索引

使用RestHighLevelClient 创建索引,需要先创建好索引字段内容

PUT /products
{
    "mappings": {
        "properties": {
            "title": {
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "price": {
                "type": "double"
            },
            "create_at": {
                "type": "date"
            },
            "description": {
                "type": "text",
                "analyzer": "ik_max_word"
            }
        }
    }
}

将索引的内容放到代码中,再执行创建索引操作

@Test
    public void testIndexAndMapping() throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("products");

        createIndexRequest.mapping("{\"properties\":{\"title\":{\"type\":\"keyword\"},\"price\":{\"type\":\"double\"},\"create_at\":{\"type\":\"date\"},\"description\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\"}}}", XContentType.JSON);

        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        System.out.println("createIndexResponse = " + createIndexResponse);

        restHighLevelClient.close();
    }

es 模板创建 es在项目中如何使用_搜索引擎_04

使用kibana看到索引创建成功

es 模板创建 es在项目中如何使用_System_05

3.1.2删除索引

删除指定索引

@Test
    public void testdeleteIndex() throws IOException {
        AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(new DeleteIndexRequest("products"), RequestOptions.DEFAULT);
        System.out.println("acknowledgedResponse = " + acknowledgedResponse.toString());
    }

es 模板创建 es在项目中如何使用_elasticsearch_06

可以看到索引被删除,执行查看索引将会报错

es 模板创建 es在项目中如何使用_java_07

3.1.3创建文档

在创建索引后,在kibaba中创建出一条数据备用

PUT /products/_doc/1
{
  "title":"脆司令",
  "price":1.5,
  "create_at":"2021-12-12",
  "description":"脆司令非常好吃"
}

创建测试类将RestHighLevelClient注入,执行创建索引并插入数据,没有指定id,会自动生成id

@SpringBootTest
public class RestHighLevClientForDocumentTests{

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Test
    public void testCreate() throws IOException {

        IndexRequest indexRequest = new IndexRequest("products");
        indexRequest.source("{\"title\":\"脆司令\",\"price\":1.5,\"create_at\":\"2021-12-12\",\"description\":\"脆司令非常好吃\"}", XContentType.JSON);

        IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("index = " + index);
    }
}

es 模板创建 es在项目中如何使用_es 模板创建_08

es 模板创建 es在项目中如何使用_elasticsearch_09

3.1.4根据id查询

@Test
    public void testQueryById() throws IOException {

        GetRequest getRequest = new GetRequest("products", "BaTgKIEBrV6nA_doTtkg");
        GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        System.out.println("id:"+getResponse.getId());
        System.out.println("getResponse.getSourceAsString() = " + getResponse.getSourceAsString());
    }

es 模板创建 es在项目中如何使用_System_10

3.1.5根据id修改

@Test
    public void testUpdate() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("products", "BaTgKIEBrV6nA_doTtkg");
        updateRequest.doc("{\"price\":0.5}",XContentType.JSON);
        UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println("update = " + update);
    }

es 模板创建 es在项目中如何使用_搜索引擎_11

es 模板创建 es在项目中如何使用_System_12

3.1.6根据id删除

@Test
    public void testDelete() throws IOException {
        DeleteResponse products = restHighLevelClient.delete(new DeleteRequest("products", "1"), RequestOptions.DEFAULT);
        System.out.println("products = " + products);
    }

es 模板创建 es在项目中如何使用_es 模板创建_13

es 模板创建 es在项目中如何使用_搜索引擎_14

3.2综合查询

进行查询之前需要准备查询数据

3.2.1创建索引

PUT /products
{
    "mappings": {
        "properties": {
            "title": {
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "price": {
                "type": "double"
            },
            "create_at": {
                "type": "date"
            },
            "description": {
                "type": "text",
                "analyzer": "ik_max_word"
            }
        }
    }
}

3.2.2添加数据

PUT /products/_doc/1
{
  "title":"脆司令",
  "price":1.5,
  "create_at":"2021-12-12",
  "description":"脆司令非常好吃"
}
PUT /products/_doc/2
{
  "title":"荷兰豆",
  "price":1.5,
  "create_at":"2021-12-12",
  "description":"荷兰豆令非常好吃"
}
PUT /products/_doc/3
{
  "title":"鱼豆腐",
  "price":1.5,
  "create_at":"2021-12-12",
  "description":"鱼豆腐非常好吃"
}

PUT /products/_doc/4
{
  "title":"小鱼干",
  "price":1.5,
  "create_at":"2021-12-12",
  "description":"小鱼干非常好吃"
}

3.2.3查询所有

创建RestHighLevClientForSearchTests测试类

@SpringBootTest
public class RestHighLevClientForSearchTests {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Test
    public void testMatchAll() throws IOException {
        SearchRequest searchRequest = new SearchRequest("products");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        searchRequest.source(sourceBuilder);

        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("总条数:"+searchResponse.getHits().getTotalHits().value);
        System.out.println("最大得分:"+searchResponse.getHits().getMaxScore());

        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            String id = hit.getId();
            System.out.println("id:"+id+"source:"+hit.getSourceAsString());
        }
    }
}

查询结果:

es 模板创建 es在项目中如何使用_java_15

3.2.4使用分词查询

@Test
    public void testQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("products");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termQuery("description","司令"));
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("符合条件总数:"+searchResponse.getHits().getTotalHits().value);
        System.out.println("获取文档最大分数:"+searchResponse.getHits().getTotalHits().value);

        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println("id:"+hit.getId()+" source:"+hit.getSourceAsString());
        }

    }

es 模板创建 es在项目中如何使用_es 模板创建_16

3.2.5根据加个查询,查询数据高亮

@Test
    public void testSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("products");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.requireFieldMatch(false).field("description").field("title").preTags("<span style='color:red'>").postTags("</span>");
        sourceBuilder.query(QueryBuilders.termQuery("description","好吃"))
                .from(0)
                .size(10)
                .sort("price", SortOrder.ASC)
                .fetchSource(new String[]{},new String[]{"create_at"})
                .highlighter(highlightBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("符合条件总数:"+searchResponse.getHits().getTotalHits().value);
        System.out.println("获取文档最大分数:"+searchResponse.getHits().getTotalHits().value);

        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println("id:"+hit.getId()+" source:"+hit.getSourceAsString());

            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if(highlightFields.containsKey("description")){
                System.out.println("description高亮结果:"+highlightFields.get("description").fragments()[0]);
            }
            if(highlightFields.containsKey("title")){
                System.out.println("title高亮的结果:"+highlightFields.get("title").fragments()[0]);
            }
        }
    }

查询结果:

es 模板创建 es在项目中如何使用_java_17

3.2.6过滤器查询

@Test
    public void testFilterQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("products");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        sourceBuilder
                .query(QueryBuilders.matchAllQuery())
                .postFilter(QueryBuilders.termQuery("description","豆腐"));

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

        System.out.println("符合条件总数:"+searchResponse.getHits().getTotalHits().value);
        System.out.println("获取文档最大分数:"+searchResponse.getHits().getTotalHits().value);

        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println("id:"+hit.getId()+" source:"+hit.getSourceAsString());
        }
    }

es 模板创建 es在项目中如何使用_java_18

3.2.7封装查询函数

public void query(QueryBuilder queryBuilder) throws IOException {
        SearchRequest searchRequest = new SearchRequest("products");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(queryBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("符合条件总数:"+searchResponse.getHits().getTotalHits().value);
        System.out.println("获取文档最大分数:"+searchResponse.getHits().getTotalHits().value);

        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println("id:"+hit.getId()+" source:"+hit.getSourceAsString());
        }
    }

查询

@Test
    public void testQuery2() throws IOException {
        query(QueryBuilders.termQuery("description","司令"));

        query(QueryBuilders.rangeQuery("price").gt(0).lte(1.66));

        query(QueryBuilders.prefixQuery("description","脆司令"));

        query(QueryBuilders.wildcardQuery("title","脆*"));

        query(QueryBuilders.idsQuery().addIds("1").addIds("2"));

        query(QueryBuilders.multiMatchQuery("非常不错","title","description"));
    }

查询结果:

es 模板创建 es在项目中如何使用_es 模板创建_19

3.3聚合查询

3.3.1准备数据

创建索引

PUT /fruit
{
  "mappings": {
    "properties": {
      "title":{
        "type": "keyword"
      },
      "price":{
        "type":"double"
      },
      "description":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

添加数据

PUT /fruit/_bulk
{"index":{}}
  {"title" : "面包","price" : 19.9,"description" : "小面包非常好吃"}
{"index":{}}
  {"title" : "旺仔牛奶","price" : 29.9,"description" : "非常好喝"}
{"index":{}}
  {"title" : "日本豆","price" : 19.9,"description" : "日本豆非常好吃"}
{"index":{}}
  {"title" : "小馒头","price" : 19.9,"description" : "小馒头非常好吃"}
{"index":{}}
  {"title" : "大辣片","price" : 39.9,"description" : "大辣片非常好吃"}
{"index":{}}
  {"title" : "透心凉","price" : 9.9,"description" : "透心凉非常好喝"}
{"index":{}}
  {"title" : "小浣熊","price" : 19.9,"description" : "童年的味道"}
{"index":{}}
  {"title" : "海苔","price" : 19.9,"description" : "海的味道"}

3.3.2根据加个聚合

@Test
    public void testAggs() throws IOException {
        SearchRequest searchRequest = new SearchRequest("fruit");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder
                .query(QueryBuilders.matchAllQuery())
                .aggregation(AggregationBuilders.terms("price_group").field("price"))
                .size(0);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        Aggregations aggregations = searchResponse.getAggregations();
        ParsedDoubleTerms parsedDoubleTerms = aggregations.get("price_group");

        List<? extends Terms.Bucket> buckets = parsedDoubleTerms.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            System.out.println(bucket.getKey()+" "+bucket.getDocCount());
        }
    }

查询结果:

es 模板创建 es在项目中如何使用_java_20

3.3.3求出价格最大的值

@Test
    public void testAggsFunction() throws IOException {
        SearchRequest searchRequest = new SearchRequest("fruit");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder
                .query(QueryBuilders.matchAllQuery())
//                .aggregation(AggregationBuilders.sum("sum_price").field("price"))
//                .aggregation(AggregationBuilders.avg("avg_price").field("price"))
                .aggregation(AggregationBuilders.max("max_price").field("price"))
                .size(0);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        Aggregations aggregations = searchResponse.getAggregations();
//        ParsedSum parsedSum = aggregations.get("sum_price");
//        System.out.println(parsedSum.getValue());
//        ParsedAvg parsedAvg = aggregations.get("avg_price");
//        System.out.println(parsedAvg.getValue());

        ParsedMax parsedMax = aggregations.get("max_price");
        System.out.println(parsedMax.getValue());

    }

es 模板创建 es在项目中如何使用_java_21