ElasticSearch--整合SpringBoot

引入依赖

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

配置客户端

@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("172.16.91.10:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}
SpringBoot提供了两种操作ES的客户端
  • RestHighLevelClient 推荐

ElasticsearchOperations

  • 特点: 始终使用面向对象方式操作 ES
    • 索引: 用来存放相似文档集合
    • 映射: 用来决定放入文档的每个字段以什么样方式录入到 ES 中 字段类型 分词器…
    • 文档: 可以被索引最小单元 json 数据格式
相关注解
  • @Document(indexName=“products”, createIndex=true) 用在类上,表示为一个ES中的文档
    • indexName属性:创建索引的名称
    • createIndex属性:是否创建索引
  • @Id 标记在属性上,将对象的 id 字段映射成文档中的 _id
  • @Field(type=FieldTpye.keyword) :表示索引中字段的类型
    • type:指定字段类型
@Document(indexName = "product", createIndex = true)
public class Product {
    @Id
    private Integer id;
    @Field(type = FieldType.Keyword)
    private String title;
    @Field(type = FieldType.Float)
    private Double price;
    @Field(type = FieldType.Text)
    private String description;
    //get set ...
}
基本操作
public class ElasticSearchOptionsTest extends ElasticsearchApplicationTests{

    private ElasticsearchOperations elasticsearchOperations;

    @Autowired
    public ElasticSearchOptionsTest(ElasticsearchOperations elasticsearchOperations){
        this.elasticsearchOperations=elasticsearchOperations;
    }


    /**
     * save:当文档id不存在时,新增文档;如果存在就修改文档
     */
    @Test
    public void testIndex(){
        Product product=new Product();
        product.setId(1);
        product.setTitle("小浣熊干脆面");
        product.setPrice(5.5);
        product.setDescription("小浣熊干脆面真好吃");
        elasticsearchOperations.save(product);
    }

    /**
     * 查询一条文档
     */
    @Test
    public void queryIndex(){
        Product product = elasticsearchOperations.get("1", Product.class);
        System.out.println(product);
    }

    /**
     * 查询所有
     */
    @Test
    public void queryAllIndex(){
        SearchHits<Product> search = elasticsearchOperations.search(Query.findAll(), Product.class);
        System.out.println("总分数: "+search.getMaxScore());
        System.out.println("符合条件的条数: "+search.getTotalHits());
        for (SearchHit<Product> searchHit : search) {
            System.out.println(searchHit.getContent());
        }
    }

    /**
     * 删除一条文档
     */
    @Test
    public void  testDelete(){
        //根据Id删除
        elasticsearchOperations.delete("1",Product.class);
        //删除所有
     elasticsearchOperations.delete(Query.findAll(),Product.class);
    }

}

RestHighLevelClient

索引操作

创建索引及映射
@Test
public void  createIndex() throws IOException {
    //创建索引请求,指定索引名
    CreateIndexRequest createIndexRequest = new CreateIndexRequest("product");
    //设置索引映射,参数1:json格式的映射结构 参数2:指定格式的类型(json)
    createIndexRequest.mapping("{\n" +
                               "    \"properties\": {\n" +
                               "      \"title\":{\n" +
                               "        \"type\": \"keyword\"\n" +
                               "      },\n" +
                               "      \"price\":{\n" +
                               "        \"type\": \"double\"\n" +
                               "      },\n" +
                               "      \"create_at\":{\n" +
                               "        \"type\": \"date\"\n" +
                               "      },\n" +
                               "      \"description\":{\n" +
                               "        \"type\": \"text\"\n" +
                               "      }\n" +
                               "    }\n" +
                               "  }", XContentType.JSON);

    //参数1:创建索引请求  ,参数2:索引请求的配置对象,一般直接用默认的
    //返回对象包含的索引的创建状态
    CreateIndexResponse response = elasticsearchClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
    //Acknowledged属性表示了索引是否创建成功
    System.out.println(response.isAcknowledged());


}
删除索引
/**
     * 删除索引
     */
    @Test
    public void testDeleteIndex() throws IOException {
        /*参数1:删除索引对象 参数2:请求配置对象*/
        //返回操作结果
        AcknowledgedResponse response = elasticsearchClient.indices().delete(new DeleteIndexRequest("product"), RequestOptions.DEFAULT);
        System.out.println("删除结果:"+response.isAcknowledged());

    }

文档操作

创建文档
 /**
      创建文档
     */
    @Test
    public void createDoc() throws IOException {

        //创建请求索引对象,需要传入索引的名称
        IndexRequest indexRequest = new IndexRequest("product");
        //可指定id,不指定就UUID,一般传入 json格式的文档
        indexRequest.id("1").source("{\n" +
                "  \"title\":\"红烧牛肉面\",\n" +
                "  \"price\":\"5.5\",\n" +
                "  \"create_at\":\"2022-04-13\",\n" +
                "  \"description\":\"红烧牛肉面真难吃\"\n" +
                "}", XContentType.JSON);

        //参数1: 索引的请求对象 ,参数2:请求配置对象
        IndexResponse response = elasticsearchClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }
更新文档
  /**
     * 更新文档
     */
    @Test
    public void updateDoc() throws IOException {
        //参数1:索引名,参数2:文档id
        UpdateRequest updateRequest = new UpdateRequest("product","1");
        updateRequest.doc("{\n" +
                "    \"description\":\"新:好饿想吃\"\n" +
                "  }",XContentType.JSON);
        UpdateResponse response = elasticsearchClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }
删除文档
 /**
     * 删除文档
     */
    @Test
    public void deleteDoc() throws  IOException{
        //参数1:索引名,参数2:id值
        DeleteRequest deleteRequest = new DeleteRequest("product","1");
        DeleteResponse response = elasticsearchClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }
查询文档
/**
     * 根据ID查询文档
     */
    @Test
    public void queryDoc() throws IOException {

        GetRequest getRequest = new GetRequest("product","1");
        GetResponse response = elasticsearchClient.get(getRequest, RequestOptions.DEFAULT);
        System.out.println("ID:"+response.getId());
        System.out.println("数据:"+response.getSourceAsString());
    }


高级查询

查询所有

/**
     * 查询所有
     */
    @Test
    public void queryAll() throws IOException {

        //指定搜索的索引
        SearchRequest searchRequest = new SearchRequest("product");
        //指定查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询所有
        sourceBuilder.query(QueryBuilders.matchAllQuery());

        searchRequest.source(sourceBuilder);

        //参数1 :搜索的请求对象 参数2:请求配置对象
        SearchResponse response = elasticsearchClient.search(searchRequest,RequestOptions.DEFAULT);
        System.out.println("总记录数:"+response.getHits().getTotalHits().value);
        System.out.println("最大得分:"+response.getHits().getMaxScore());

        //获取结果
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            System.out.println("Id:"+hit.getId());
            System.out.println("source:"+hit.getSourceAsString());
        }


    }

关键词查询

/**
     * 不同条件查询 term(关键词查询)
     */
    @Test
    public void termQuery() throws IOException {

        //指定搜索的索引
        SearchRequest searchRequest = new SearchRequest("product");
        //指定查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termQuery("description","吃"));
        searchRequest.source(sourceBuilder);
        SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("符合条件的数量:"+response.getHits().getTotalHits().value);;
        System.out.println("获得文档最大分数:"+response.getHits().getMaxScore());;

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

        }
    }

封装高级查询

public void queryBasic(QueryBuilder queryBuilder) throws IOException {
        //指定搜索的索引
        SearchRequest searchRequest = new SearchRequest("product");
        //指定查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(queryBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("符合条件的数量:"+response.getHits().getTotalHits().value);;
        System.out.println("获得文档最大分数:"+response.getHits().getMaxScore());;

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

        }
    }

    /**
     * 封装查询
     * @throws IOException
     */
    @Test
    public void queryTest() throws IOException {
        //1.term 关键词查询
        queryBasic(QueryBuilders.termQuery("description","吃"));
        //2.range  范围查询
        queryBasic(QueryBuilders.rangeQuery("price").gt(0).lte(10));
        //3.prefix 前缀查询
        queryBasic(QueryBuilders.prefixQuery("description","红烧牛肉面"));
        //4.wildcard 通配符查询  ?表示一个字符  *表示任意个字符
        queryBasic(QueryBuilders.wildcardQuery("title","红烧*"));
        //5.ids 多个指定id查询
        queryBasic(QueryBuilders.idsQuery().addIds("1").addIds("2"));
        //6.multi_math 多字段查询
        queryBasic(QueryBuilders.multiMatchQuery("红烧","title","description"));
    }
综合查询
/*
        1.关键字查询 term
        2.分页查询 from size
        3.排序  sort
        4.返回指定的字段 fetchSource 用来指定查询返回的字段
     */
    @SneakyThrows
    @Test
    public void queryLimit() throws IOException {
        SearchRequest searchRequest = new SearchRequest("product");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //创建高亮器
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.requireFieldMatch(false).field("description").preTags("<span style='color:red;'>").postTags("</span>");


        searchSourceBuilder.query(QueryBuilders.termQuery("description","面"))
                .from(0) //起始位置   (page-1)*size
                .size(1) //每页的数量

                .sort("price", SortOrder.DESC) // 1.排序的字段 2.排序的方式
                .fetchSource(new String[]{}, new String[]{"create_at"}) // 1.包含的字段  2.想要排除的字段
                    .highlighter(highlightBuilder); //高亮查询

        searchRequest.source(searchSourceBuilder);
        SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);

        System.out.println("符合条件的数量:" + response.getHits().getTotalHits().value);

        System.out.println("获得文档最大分数:" + response.getHits().getMaxScore());


        SearchHit[] hits = response.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]);
            }

        }

    }
基于对象操作

Java类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Snacks {

    private Integer id;

    private String title;

    private Double price;

    private String description;
}

测试

/*
      将对象放入 ES中
     */
    @Test
    public  void createIndex() throws IOException {
        Snacks snacks = new Snacks();
        snacks.setId(1);
        snacks.setTitle("卫龙辣条");
        snacks.setPrice(0.5);
        snacks.setDescription("辣条真好吃");

        IndexRequest indexRequest = new IndexRequest("snacks");
        indexRequest.id(snacks.getId().toString())
            		//将对象转化为Json
                    .source(new ObjectMapper().writeValueAsString(snacks), XContentType.JSON);


        IndexResponse response = elasticsearchClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("创建结果:"+response.status());
    }

    @Test
    public void queryTest() throws IOException {

        SearchRequest searchRequest = new SearchRequest("snacks");

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.requireFieldMatch(false).field("description").preTags("<span style='color:red;'>").postTags("</span>");
        sourceBuilder.query(QueryBuilders.termQuery("description","好吃"))
                     .highlighter(highlightBuilder);


        searchRequest.source(sourceBuilder);

        SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);

        SearchHit[] hits = response.getHits().getHits();
        List<Snacks> list=new ArrayList<>();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
            //将json转换为对象
            Snacks snacks = new ObjectMapper().readValue(hit.getSourceAsString(), Snacks.class);

            //处理高亮
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (highlightFields.containsKey("description")){
                snacks.setDescription(highlightFields.get("description").fragments()[0].toString());
            }
            list.add(snacks);
        }

        for (Snacks snacks : list) {
            System.out.println(snacks);
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值