Spring Data Elasticsearch配置及使用

Spring Data Elasticsearch

以POJO为中心模型用于与Elastichsearch文档交互,并轻松编写存储库样式的数据访问层框架

我们学习的是底层封装了Rest High Level的ElasticsearchRestTemplate模板类型。需要使用Java API Client(Transport),则应用ElasticsearchTemplate模板类型即可。两种类型中的方法API几乎完全一样,学会了一个,另外一个主要就是配置和类型的区别。当然了,每个不同版本的框架,在方法API上还是有些差异的。

Spring Data Elasticsearch访问Elasticsearch

准备环境

1.导入依赖

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

2.yml配置

# ElasticsearchRestTemplate客户端的配置
spring:
  elasticsearch:
    rest:
      uris: http://127.0.0.1:9200  # ES服务器所在位置。集群多节点地址用逗号分隔。默认http://localhost:9200

3.创建实体类

 * 	Document - 描述类型和索引的映射。
 *  indexName - 索引名称
 *  shards - 主分片数量。默认值 1*  replicas - 副本分片数量。默认值 1@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "xy_student",shards = 1,replicas = 0)
public class Student {
    
    
	 * Id - 当前注解所在字段和主键值一致,没有次注解,则自动生成主键
     * Field - 当前属性和索引中的字段映射规则。
     *  name - 字段名称。默认和当前类型属性名一致。
     *  type - 字段类型。默认使用FieldType.AUTO。自动识别。
     *  analyzer - 分词器。所有的Text类型字段默认使用standard分词器。
     *  index - 是否创建索引。默认值 true*  format - 如果字段类型是date日期类型。此属性必须配置,用于设置日期格式化规则,使用DateFormat类型中的常量定义。

	@Id
    @Field(name="sid",type = FieldType.Integer)
    private Integer sid;

    @Field(name="sname",type = FieldType.Text,analyzer = "ik_max_word")
    private String sname;

    @Field(name="score",type = FieldType.Double)
    private Double score;

    @Field(name="birth",type = FieldType.Date,format = DateFormat.year_month_day)
    private Date birth;
}

索引操作

@Autowired
private ElasticsearchRestTemplate restTemplate;
    
IndexOperations indexOps = restTemplate.indexOps(Student.class);
1.创建索引
indexOps.create();

2.设置映射: 在商业开发中,几乎不会使用框架创建索引或设置映射。因为这是架构或者管理员的工作。且不适合使用代码实现
indexOps.putMapping(indexOps.createMapping());

3.删除索引
restTemplate.indexOps(Student.class).delete();

文档操作

简单CURD

1.新增文档
如果索引不存在,新增文档时自动创建索引。但是不使用类上的映射配置,使用默认映射.所以一定要先通过代码进行mapping设置,或直接在elasticsearch中通过命令创建所有field的mapping(推荐)
Student zs = elasticsearchRestTemplate.save(new Student(1, "zs", 0.55, new Date()));
System.out.println(zs);

2.批量新增文档
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student(1, "zs", 0.55, new Date()));
        students.add(new Student(2, "sdf", 0.22, new Date()));
        students.add(new Student(3, "df", 0.33, new Date()));
        Iterable<Student> save = elasticsearchRestTemplate.save(students);
        System.out.println(save.toString());
        
3.主键查询文档
Student student = restTemplate.get("3", Student.class);

4.删除文档
    // 删除类型对应的索引中的指定主键数据,返回删除数据的主键。注意:Elasticsearch中的文档主键都是字符串类型的。
    String response = restTemplate.delete("1", Student.class);

5.更新文档
 * save方法,可以覆盖同主键数据。全量替换
 * update更新,部分更新
@Test
public void testUpdate(){
    
    
    UpdateQuery query =UpdateQuery.builder("2")
                    			  .withDocument(Document.parse("{\"hobbies\":[\"郭麒麟\", \"郭汾阳\"]}"))
                    			  .build();
    UpdateResponse response = restTemplate.update(query, IndexCoordinates.of("stu_index"));
    System.out.println(response.getResult());
}

query string 查询

    @Test
    void contextsxLsoads() {
    
    
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("sname:zs");
        Query query = new NativeSearchQueryBuilder()
                        .withQuery(queryBuilder) // 提供具体的条件。
                        .build();

        SearchHits<Student> hits = elasticsearchRestTemplate.search(query, Student.class);
        System.out.println("搜索结果数据个数是: " + hits.getTotalHits());

        for (SearchHit<Student> hit : hits) {
    
    
            // 源数据,就是保存在Elasticsearch中的数据
            Student content = hit.getContent();
            System.out.println("源数据:" + content);
        }
    }

DSL 查询

1.搜索全部
@Test
public void testMatchAll(){
    
    
    SearchHits<Student> hits = restTemplate.search(
            new NativeSearchQueryBuilder()
                    .withQuery(QueryBuilders.matchAllQuery())
                    .build(), Student.class);
    for(SearchHit<Student> hit : hits){
    
    
        System.out.println(hit.getContent());
    }
}
2.match搜索
SearchHits<Student> hits = restTemplate.search(
            new NativeSearchQueryBuilder()
                    .withQuery(
                            QueryBuilders.matchQuery(
                                    "name",
                                    "于谦")
                    ).build(),Student.clas);

3.短语搜索,完全匹配Match Phrase
    SearchHits<Student> hits = restTemplate.search(
            new NativeSearchQueryBuilder()
                    .withQuery(
                            QueryBuilders.matchPhraseQuery(
                                    "hobbies",
                                    "烫头"
                            )
                    )
                    .build(),
            Student.class
    );

4.范围搜索Range 搜索
    SearchHits<Student> hits =
            restTemplate.search(
                    new NativeSearchQueryBuilder()
                            .withQuery(
                                    QueryBuilders.rangeQuery("age")
                                    .lte(35).gte(30)
                            )
                            .build(),
                    Student.class
            );

5.Bool 搜索,多条件同时满足
    @Test
    void contextswLsoads() {
    
    
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        List<QueryBuilder> must = boolQueryBuilder.must();
        must.add(QueryBuilders.matchQuery("sname","zs"));
        must.add(QueryBuilders.rangeQuery("score").gt(0).lt(0.5));

        Query queryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).build();

        SearchHits<Student> search = elasticsearchRestTemplate.search(queryBuilder, Student.class);
    }

6.分页和排序
 * PageRequest类型中,提供静态方法of(int page, int size[, Sort sort]);
 * page - 查询第几页,页码数字从0开始计数。
 * size - 查询多少行。
 * Sort - 具体的排序规则。可选参数。
    SearchHits<Student> hits =
            restTemplate.search(
                    new NativeSearchQueryBuilder()
                            .withQuery(QueryBuilders.matchAllQuery())
                            .withPageable(
                                    PageRequest.of(0, 2,
                                            Sort.by(
                                                    Sort.Order.desc("age"),
                                                    Sort.Order.asc("id")
                                            )
                                    )
                            )
                            .build(),
                    Student.class
            );

7.高亮处理
@Test
public void testQueryHighLight(){
    
    
    // 创建高亮字段,必须和具体的字段名绑定。
    HighlightBuilder.Field field1 = new HighlightBuilder.Field("name");
    // 高亮前缀
    field1.preTags("<span style='color: red'>");
    // 高亮后缀
    field1.postTags("</span>");
    // 分段的每段字符数
    field1.fragmentSize(Integer.MAX_VALUE);
    // 分段后,返回几段
    field1.numOfFragments(1);
    Query query =
            new NativeSearchQueryBuilder()
                    .withQuery(
                            QueryBuilders.matchQuery(
                                    "name",
                                    "于谦")
                    )
                    .withHighlightFields(field1)
                    .build();

    SearchHits<Student> hits =
            restTemplate.search(query, Student.class);

    for (SearchHit<Student> hit : hits){
    
    
        // 获取源数据
        Student content = hit.getContent();
        // 找高亮数据
        List<String> hl = hit.getHighlightField("name");
        // 判断是否有高亮数据
        if(hl != null && hl.size() > 0){
    
    
            // 有高亮数据
            content.setName(hl.get(0));
        }
        System.out.println(content);
    }

}

猜你喜欢

转载自blog.csdn.net/m0_56182317/article/details/130263080