ElasticsearchTemplate 的API

前言

ElasticSearchTemplate 依赖 spring-boot-starter-data-elasticsearch, 对于ES7不适用, 本案例演示是基于ElasticSerach-6.4.3 的

相关依赖

pom:



    
        foodie-dev
        com.imooc
        1.0-SNAPSHOT
    
    4.0.0

    foodie-search
    
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.boot
            spring-boot-starter-data-elasticsearch
            2.1.5.RELEASE
        
    

yml:

spring:
  datasource:                                           # 数据源的相关配置
    type: com.zaxxer.hikari.HikariDataSource          # 数据源类型:HikariCP
    driver-class-name: com.mysql.jdbc.Driver          # mysql驱动
    url: jdbc:mysql://192.168.209.151:3306/foodie_shop_dev?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=true
    username: root
    password: root
  data:
    elasticsearch:
      cluster-name: imooc-es-cluster	# elasticsearch.yml 中配置集群名
      cluster-nodes: 192.168.209.151:9300	# 集群节点, 注意开放给客户端的端口是 9300

与索引库的 mapping结构匹配的实体类:

package com.imooc.es.pojo;

import lombok.Data;
import lombok.ToString;
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;

/**
 * Created by robbyzhan on 2020/1/24.
 */
@Document(indexName = "stu", type = "_doc")	// 索引库名称和 type
@Data
@ToString
public class Stu {
    @Id     // 指定此字段和索引库id 一致(索引库id是索引为某条文档分配的 "主键")
    private Long stuId;

    @Field(store = true)
    private String name;

    @Field(store = true)
    private Integer age;

    @Field(store = true)
    private Float money;

	// 此字段类型为 keyword, 即需要输入完整 keyword, 才会找到对应文档
    @Field(store = true, type = FieldType.Keyword)	
    private String sign;

    @Field(store = true)
    private String description;
}

测试实例

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class ESTest {
    @Autowired
    private ElasticsearchTemplate esTemplate;

    // 修改文档
    @Test
    public void updateStuDoc() {
   		// 使用 Map存储文档内容(ES的一个文档, 相当于Mysql 的一个记录)
        Map sourceMap = new HashMap<>();
        sourceMap.put("sign", "I am not super man");
        sourceMap.put("money", 99.8f);
        sourceMap.put("age", 33);

        IndexRequest indexRequest = new IndexRequest();
        indexRequest.source(sourceMap);		// 文档内容封装在 map中

        UpdateQuery updateQuery = new UpdateQueryBuilder()	// 修改文档
                .withClass(Stu.class)	// 指定索引
                .withId("1002")	// 指定索引库 id
                .withIndexRequest(indexRequest)
                .build();
        esTemplate.update(updateQuery);
    }

    // 获取文档信息
    @Test
    public void getStuDoc() {
        GetQuery query = new GetQuery();
        query.setId("1002");	// 指定查找的索引 id
        Stu stu = esTemplate.queryForObject(query, Stu.class);	// 把一个文档和实体类作映射
        System.out.println(stu);
    }

    @Test
    public void deleteStuDoc() {	//删除指定文档
        esTemplate.delete(Stu.class, "1002");
    }

    // 分页
    @Test
    public void searchStuDoc() {
        Pageable pageable = PageRequest.of(0, 3);	// 指定页码(0开始), 和每页文档数
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("description", "I'm")) // 附加查询条件(查询字段以及 keyword)
                .withPageable(pageable)     // 附加分页信息
                .build();
        // 执行分页查询
        AggregatedPage pagedStu = esTemplate.queryForPage(query, Stu.class);
        System.out.println("检索后的总分页数目为:" + pagedStu.getTotalPages());
        // 获取分页数据
        List stuList = pagedStu.getContent();
        for (Stu s : stuList) {
            System.out.println(s);
        }
    }

    // 获取高亮数据
    @Test
    public void highlightStuDoc() {
        String preTag = "";
        String postTag = "";

        Pageable pageable = PageRequest.of(0, 10);
        SortBuilder sortBuilder = new FieldSortBuilder("money")
                .order(SortOrder.ASC);	// 设定 "money" 字段, 顺序排序
        SortBuilder sortBuilderAge = new FieldSortBuilder("age")
                .order(SortOrder.ASC);	// 设定 "age" 字段, 顺序排序(因为"money"在前, 所以"money" 优先)

        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("description", "a"))  // 设定查询条件
                .withHighlightFields(new HighlightBuilder.Field("description")  // 设定高亮属性和格式
                        .preTags(preTag)
                        .postTags(postTag))
                .withSort(sortBuilder)      // 设定排序规则
                .withSort(sortBuilderAge)
                .withPageable(pageable)  // 设置分页条件
                .build();
        AggregatedPage pagedStu = esTemplate.queryForPage(query, Stu.class, new SearchResultMapper() {
            @Override
            public  AggregatedPage mapResults(SearchResponse response, Class clazz, Pageable pageable) {

                List stuListHighlight = new ArrayList<>();

                SearchHits hits = response.getHits();		// 获取命中文档
                for (SearchHit h : hits) {
                    HighlightField highlightField = h.getHighlightFields().get("description");
                    // 获得高亮字段的文本
                    String description = highlightField.getFragments()[0].toString();
					// 非高亮字段值, 从命中文档中获得
                    Object stuId = (Object)h.getSourceAsMap().get("stuId");
                    String name = (String)h.getSourceAsMap().get("name");
                    Integer age = (Integer)h.getSourceAsMap().get("age");
                    String sign = (String)h.getSourceAsMap().get("sign");
                    Object money = (Object)h.getSourceAsMap().get("money");

                    Stu stuHL = new Stu();
                    stuHL.setDescription(description);
                    stuHL.setStuId(Long.valueOf(stuId.toString()));
                    stuHL.setName(name);
                    stuHL.setAge(age);
                    stuHL.setSign(sign);
                    stuHL.setMoney(Float.valueOf(money.toString()));

                    stuListHighlight.add(stuHL);
                }

                if (stuListHighlight.size() > 0) {
                    return new AggregatedPageImpl<>((List)stuListHighlight);
                }
                return null;
            }
        });
        System.out.println("检索后的总分页数目为:" + pagedStu.getTotalPages());
        List stuList = pagedStu.getContent();
        for (Stu s : stuList) {
            System.out.println(s);
        }
    }
}

尤其需要注意的是, 设置高亮后, 如果不使用 SearchResponse, 获得命中文档, 是无法显示高亮的

你可能感兴趣的:(Elasticsearch)