SpringDataElasticSearch框架

1,838 阅读2分钟

SpringDataElasticSearch框架

依赖关系
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.3.2.RELEASE</version>
	<relativePath/> 
</parent>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<properties>
	<java.version>1.8</java.version>
	<elasticsearch.version>7.10.2</elasticsearch.version>
</properties>
配置yml
spring:
  elasticsearch:
    rest:
      uris:
        - xxx.xxx.xxx.xxx:9200
配置实体类和Document的对应关系
  1. @Document(indexName = "cube_goods", shards = 5, replicas = 1)//配置对应的索引库、分片数、副本数
  2. @Id //指定id
  3. @Field(index = true, store = true, type = FieldType.Text, analyzer = "ik_smart")

@Data
@Document(indexName = "blog_1", shards = 5, replicas = 1)
public class Blog {
    @Id
    @Field(type = FieldType.Long)
    private long id;
    @Field(type = FieldType.Text, analyzer = "ik_max_word", store = true)
    private String title;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String content;
    @Field(type = FieldType.Text, analyzer = "ik_max_word", store = true)
    private String comment;
    @Field(type = FieldType.Keyword, store = true)
    private String mobile;
}
文档的管理ElasticSearchRepository接口
使用方法

创建一个接口,继承与ElasticSearchRepository,指定使用的Entity类及对应主键数据类型,Springboot自动扫描接口并创建代理对象

  1. 新增、更新数据
    • 使用repository的save方法实现
  2. 删除数据
    • deleteById
    • deleteAll
  3. 查询数据
    • 可以使用repository自带的查询方法
      • findById
      • findAll
    • 可以自定义查询方法
      • findBy{Titlte}And{contnet}(String title, String content); 按照命名规则定义方法,就可以实现相应的查询
public interface BlogRepostory extends ElasticsearchRepository<Blog, Long> {
    //按照命名规则定义方法
    List<Blog> findByTitle(String title);
    List<Blog> findByContent(String content, Pageable page);
}

@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogRepostoryTest {
    @Autowired
    private BlogRepostory repostory;

    @Test
    public void testFindByTitle() {
        List<Blog> blogs = repostory.findByTitle("电影");
        blogs.forEach(System.out::println);
    }

    @Test
    public void testFindByPage() {
        List<Blog> list = repostory.findByContent("电影", PageRequest.of(0, 5));
        list.forEach(e-> System.out.println(e));
    }

}
使用ElasticSearchRestTemplate对象(复杂查询使用这个)
1)创建索引库

​ template.indexOps(IndexCoordinates.of("mytest")).create();

2)设置mapping信息

​ 需要创建一个实体类,其中配置实体类和文档的映射关系,使用注解配置

​ 可以从Entity中生成mapping信息

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticSearchTemplateTest {
    @Autowired
    private ElasticsearchRestTemplate template;

    @Test
    public void createIndex() {
        //template.indexOps(Blog.class).create();//从实体类中创建
        template.indexOps(IndexCoordinates.of("hello_1")).create();//指定名称创建
    }

    @Test
    public void putMappiing() {
        Document mapping = template.indexOps(Blog.class).createMapping();//从实体类中创建
        template.indexOps(Blog.class).putMapping(mapping);
    }
}
3)查询
  1. 封装查询条件 NativeSearchQuery

  2. 执行查询 SearchHits searchHits = template.search(query, Blog.class);

  3. 结果处理

    • 查询到的记录数 searchHits.getTotalHits();

    • 查询的记录结果集 List<SearchHit> searchHits1 = searchHits.getSearchHits(); 然后遍历

      • 查询的记录 e.getContent()

      • 高亮结果 Map<String, List> highlightFields = e.getHighlightFields();

        List title = highlightFields.get("title");

      • 聚合结果 Map<String, Aggregation> stringAggregationMap = searchHits.getAggregations().asMap();

        Aggregation aggregation = stringAggregationMap.get("mobile_count");

        ParsedValueCount valueCount = searchHits.getAggregations().get("mobile_count");

        System.out.println(aggregation.getName());System.out.println(valueCount.getValue());


    @Test
    public void testQuery() {
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.termQuery("title", "电影"))
                .withHighlightBuilder(new HighlightBuilder().field("title").preTags("<em>").postTags("</em>"))
                .withFilter(QueryBuilders.termQuery("title", "湖南"))
                .addAggregation(AggregationBuilders.count("mobile_count").field("mobile"))
                .build();
        SearchHits<Blog> searchHits = template.search(query, Blog.class);
        long totalHits = searchHits.getTotalHits();
        System.out.println(totalHits);
        List<SearchHit<Blog>> searchHits1 = searchHits.getSearchHits();
        searchHits1.forEach(e->{
            Blog content = e.getContent();
            System.out.println(content);
            Map<String, List<String>> highlightFields = e.getHighlightFields();
            List<String> title = highlightFields.get("title");
            System.out.println(title);
        });
        Map<String, Aggregation> stringAggregationMap = searchHits.getAggregations().asMap();
        System.out.println(stringAggregationMap);
        Aggregation aggregation = stringAggregationMap.get("mobile_count");
        ParsedValueCount valueCount = searchHits.getAggregations().get("mobile_count");
        System.out.println(aggregation == valueCount);
        System.out.println(aggregation.getName());
        System.out.println(valueCount.getValue());
    }