Spring全家桶之SpringData——SpringDataElasticSearch

2021-03-04 15:23:57 浏览数 (1)

简介

使用 Spring Data 下二级子项目 Spring Data Elasticsearch 进行操作。 支持 POJO 方 法操作 Elasticsearch。相比 Elasticsearch 提供的 API 更加简单更加方便。

前提

  • 安装ELK, 配置中文分词器
  • 熟悉ES的基本操作
  • 熟悉SpringData相关开发方式

实现

搭建SpringDataElasticSearch框架

相关操作

创建索引

createIndex(): 创建索引,创建出来的索引是不带有 mapping 信息的。返回值表示是 否创建成功 putMapping():为已有的索引添加 mapping 信息。不具备创建索引的能力。返回值表 示是否创建成功

代码语言:javascript复制
 /**
	     * 创建索引,并设置映射。
	     * 需要通过两次访问实现,1、创建索引;2、设置映射。
	     */
	    @Test
	    public void testInitIndex(){
	        // 创建索引,根据类型上的Document注解创建
	        boolean isCreated = restTemplate.createIndex(Item.class);
	        // 设置映射,根据属性上的Field注解设置 0201
	        boolean isMapped = restTemplate.putMapping(Item.class);
	        System.out.println("创建索引是否成功:"   isCreated);
	        System.out.println("设置映射是否成功:"   isMapped);
	    }

在kibana的dev tools中查看

代码语言:javascript复制
//查询索引
GET _cat/indices
//查询mapping映射
GET hrt-item/_mapping

删除索引

代码语言:javascript复制
/**
     * 删除索引
     */
    @Test
    public void deleteIndex(){
        // 扫描Item类型上的Document注解,删除对应的索引。
        boolean isDeleted = restTemplate.deleteIndex(Item.class);
        System.out.println("删除Item对应索引是否成功:"   isDeleted);
        // 直接删除对应名称的索引。
        isDeleted = restTemplate.deleteIndex("test_index3");
        System.out.println("删除default_index索引是否成功:"   isDeleted);
    }

在kibana的dev tools中查看

代码语言:javascript复制
//查询索引
GET _cat/indices

新增文档

如果索引和类型不存在,也可以执行进行新增,新增后自动创建索引和类型。但是 field 通过动态 mapping 进行映射,elaticsearch 根据值类型进行判断每个属性类型,默认每个属性都是 standard 分词器,ik 分词器是不生效的。所以一定要先通过代码进行初始化或直接在 elasticsearch 中通过命令创建所有 field 的 mapping

如果对象的 id 属性没有赋值,让 ES 自动生成主键,存储时 id 属性没有值,_id 存储 document 的主键值。 如果对象的 id 属性明确设置值,存储时 id 属性为设置的值,ES 中 document 对象的 _id 也是设置的值

代码语言:javascript复制
    /**
     * 新增数据到ES
     */
    @Test
    public void testInsert(){
        Item item = new Item();
        item.setId("19216811");
        item.setTitle("沃什.伊戈.史莱姆");
        item.setSellPoint("关于我成为史莱姆却因为铺垫太长遭人骂这档事");
        item.setPrice(996666L);
        item.setNum(233);

        //这个是构建器放入的方式
        IndexQuery indexQuery = new IndexQueryBuilder() // 创建一个IndexQuery的构建器
                                    .withObject(item) // 设置要新增的Java对象
                                    .build(); // 构建IndexQuery类型的对象。
        //这个是直接放入的方式
//        IndexQuery query = new IndexQuery();
//        query.setObject(item);
        // index逻辑,相当于使用PUT请求,实现数据的新增。
        String result = restTemplate.index(indexQuery);
        System.out.println(result);
    }

在kibana的dev tools中查看

代码语言:javascript复制
//查询改索引下所有文档
GET hrt-item/_search

批量新增文档

代码语言:javascript复制
/**
     * 批量新增
     * bulk操作
     */
    @Test
    public void testBatchInsert(){
        List<IndexQuery> queries = new ArrayList<IndexQuery>();
        Item item = new Item();
        item.setId("20210224");
        item.setTitle("IPHONE 12 手机");
        item.setSellPoint("很贵");
        item.setPrice(499900L);
        item.setNum(999);
        queries.add(new IndexQueryBuilder().withObject(item).build());
        item = new Item();
        item.setId("20210225");
        item.setTitle("华为P40照相手机");
        item.setSellPoint("可以拍月亮");
        item.setPrice(599900L);
        item.setNum(999);
        queries.add(new IndexQueryBuilder().withObject(item).build());
        item = new Item();
        item.setId("20210226");
        item.setTitle("红米k30");
        item.setSellPoint("大品牌值得信赖");
        item.setPrice(699900L);
        item.setNum(999);
        queries.add(new IndexQueryBuilder().withObject(item).build());
        // 批量新增,使用的是bulk操作。
        restTemplate.bulkIndex(queries);
    }

在kibana的dev tools中查看

代码语言:javascript复制
//查询改索引下所有文档
GET hrt-item/_search

删除文档

根据主键删除 delete(String indexName,String typeName,String id); 通过字符串指定索引,类型 和 id 值delete(Class,String id) 第一个参数传递实体类类类型,建议使用此方法,减少索引名 和类型名由于手动编写出现错误的概率。 返回值为 delete 方法第二个参数值(删除文档的主键值)

代码语言:javascript复制
    /**
     * 删除文档
     */
    @Test
    public void testDelete(){
        // 根据主键删除, 常用
        String result = restTemplate.delete(Item.class, "192168111");
        System.out.println(result);

        // 根据查询结果,删除查到的数据。 应用较少。
        /*DeleteQuery query = new DeleteQuery();
        query.setIndex("hrt-item");
        query.setType("item");
        query.setQuery(QueryBuilders.matchQuery("title", "沃什.伊戈.史莱姆1"));
        restTemplate.delete(query, Item.class);*/
    }

在kibana的dev tools中查看

代码语言:javascript复制
//查询改索引下所有文档
GET hrt-item/_search

修改文档

修改操作就是新增代码,只要保证主键 id 已经存在,新增就是修改。 如果使用部分更新,则需要通过 update 方法实现。具体如下:

代码语言:javascript复制
/**
     * 修改文档
     * 如果是全量替换,可以使用index方法实现,只要主键在索引中存在,就是全量替换。<=>新增or批量新增操作
     * 如果是部分修改,则可以使用update实现。
     */
    @Test
    public void testUpdate() throws Exception{
        UpdateRequest request = new UpdateRequest();
        request.doc(
                XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "测试update更新数据,商品名称")
                        .endObject()
        );
        UpdateQuery updateQuery =
                new UpdateQueryBuilder()
                        .withUpdateRequest(request)
                        .withClass(Item.class)
                        .withId("20210224")
                        .build();
        restTemplate.update(updateQuery);
    }

在kibana的dev tools中查看

代码语言:javascript复制
//查询改索引下所有文档
GET hrt-item/_search

搜索所有数据

代码语言:javascript复制
 /**
     * 搜索所有数据
     */
    @Test
    public void testMatchAll(){
        /*
         * SearchQuery - 是Spring Data Elasticsearch中定义的一个搜索接口
         * NativeSearchQuery - 是SearchQuery接口的实现类。
         *  构造的时候,需要提供一个QueryBuilder类型的对象,
         *  QueryBuilder是Elasticsearch的java客户端中定义的搜索条件类型。
         *
         * QueryBuilders - 是QueryBuilder类型的工具类,可以快速实现QueryBuilder类型对象的创建
         *  工具类中,提供了大量的静态方法,方法命名和DSL搜索中的条件关键字相关。
         *  如:match_all 对应 matchAllQuery()
         *  如:match 对应 matchQuery()
         *  如:range 对应 rangeQuery()
         */
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.matchAllQuery()
        );
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

条件搜索 or 模糊搜索

去所有 field 中搜索指定条件。 在kibana的dev tools中修改之前批量新增的一个数据, 目的是当我们搜索华为Mate40 时, 不仅能够搜索到

代码语言:javascript复制
PUT hrt-item/item/20210226
{
  "id" : "20210226",
          "title" : "华为荣耀手机",
          "sellPoint" : "打游戏值得拥有",
          "price" : 399900,
          "num" : 999
}
代码语言:javascript复制
    /**
     * 条件搜索
     */
    @Test
    public void testMatch(){
        SearchQuery query = new NativeSearchQuery(QueryBuilders.matchQuery("title", "华为mate40"));
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

短语搜索

短语搜索是对条件不分词,但是文档中属性根据配置实体类时指定的分词类型进行分词。 如果属性使用 ik 分词器,从分词后的索引数据中进行匹配。

代码语言:javascript复制
	/**
     * 短语搜索
     * 只要被分词后锁短语含有, 则都会被搜索到
     */
    @Test
    public void testMatchPhrase(){
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.matchPhraseQuery("title", "华为mate40")
        );
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

词组搜索

代码语言:javascript复制
	/**
     * 词组搜索
     * 只有没有被切分的词组才能搜到结果, 例如: 华为荣耀已被切分, 则搜索不到; 而荣耀 不会被切分因此能够搜索到结果
     * 区别于短语搜索
     */
    @Test
    public void testTerm(){
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.termQuery("title", "mate40")
        );
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

范围搜索

代码语言:javascript复制
/**
     * 范围搜索 range
     * gte <==> 小于等于 ; gt <==> 小于 
     * lte <==> 大于等于 ; lt <==> 大于
     */
    @Test
    public void testRange(){
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.rangeQuery("price").gte(500000L).lte(400000L)
        );
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

复合条件搜索

代码语言:javascript复制
/**
     * 复合条件搜索
     */
    @Test
    public void testBool(){
        // 创建一个Bool搜索条件。 相当于定义 bool:{ must:[], should:[], must_not:[] }
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        List<QueryBuilder> mustList = builder.must();
        //词组所搜 范围搜索
        mustList.add(QueryBuilders.matchQuery("title", "华为"));
        mustList.add(QueryBuilders.rangeQuery("price").gte(300000L));
        // builder.mustNot();
        // builder.should();
        SearchQuery query = new NativeSearchQuery(builder);
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

分页和排序搜索

如果实体类中主键只有@Id 注解,String id 对应 ES 中是 text 类型,text 类型是不允许被排序,所以如果必须按照主键进行排序时需要在实体类中设置主键类型 @Id @Field(type = FieldType.Keyword) private String id;

代码语言:javascript复制
/**
     * 分页和排序
     * 所有的Spring Data子工程中的分页和排序逻辑使用的都是相似的方式。
     * 根据PageRequest和Sort实现分页或排序。
     */
    @Test
    public void testPageable(){
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.matchAllQuery()
        );
        // 设置分页
        query.setPageable(PageRequest.of(0, 2));
        // 设置排序
        query.addSort(Sort.by(Sort.Direction.DESC, "price"));
        // 设置分页的同时设置排序
        // query.setPageable(PageRequest.of(0, 2, Sort.by(Sort.Direction.DESC, "price")))
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

高亮搜索

以上操作详见 ES 教程的 第六部分的3.1 - 3.6 , 有对应DSL操作的演示

代码语言:javascript复制
	/**
     * 高亮
     */
    @Test
    public void testHighlight(){
        HighlightBuilder.Field field = new HighlightBuilder.Field("title");
        field.preTags("");
        field.postTags("");

        NativeSearchQuery query =
                new NativeSearchQueryBuilder()
                        // 排序
                        .withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC))
                        // 分页
                        .withPageable(PageRequest.of(0, 2))
                        // 搜索条件
                        .withQuery(QueryBuilders.matchQuery("title", "华为"))
                        // 设置高亮字段
                        .withHighlightFields(field)
                        .build();

        AggregatedPage<? extends Item> pageResult =
                restTemplate.queryForPage(query, Item.class, new SearchResultMapper() {
                    // 处理搜索结果,搜索的完整结果,也就是那个集合。
                    // response - 就是搜索的结果,相当于在Kibana中执行搜索的结果内容。
                    // clazz - 就是返回结果的具体类型
                    // pageable - 分页处理,就是queryForPage方法参数query中的pageable对象。
                    public <T> AggregatedPage<T> mapResults(SearchResponse response,
                                                            Class<T> clazz,
                                                            Pageable pageable) {
                        // 获取搜索的结果数据
                        SearchHit[] hits = response.getHits().getHits();
                        List<T> resultList = new ArrayList<T>();
                        for(SearchHit hit : hits){
                            // 搜索的source源
                            Map<String, Object> map = hit.getSourceAsMap();
                            Item item = new Item();
                            item.setId(map.get("id").toString());
                            item.setSellPoint(map.get("sellPoint").toString());
                            item.setPrice(Long.parseLong(map.get("price").toString()));
                            item.setNum(Integer.parseInt(map.get("num").toString()));
                            // 高亮数据处理。key - 字段名, value - 是高亮数据结果
                            Map<String, HighlightField> highlightFieldMap = hit.getHighlightFields();
                            HighlightField highlightField = highlightFieldMap.get("title");
                            if (highlightField == null){ // 没有高亮的title
                                item.setTitle(map.get("title").toString());
                            }else{ // 有高亮的title
                                item.setTitle(highlightField.getFragments()[0].toString());
                            }
                            resultList.add((T)item);
                        }
                       // 返回处理后的结果

                        return new AggregatedPageImpl<T>(
                                resultList, pageable, response.getHits().getTotalHits()
                        );
                    }

                    // 不提供实现,这个是处理每个搜索结果的方法
                    public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
                        return null;
                    }
                });

        for(Item item : pageResult.getContent()){
            System.out.println(item);
        }
    }

测试类整体代码如下:

代码语言:javascript复制
package com.hrt.test;


import com.hrt.SpringbootEsApplication;
import com.hrt.pojo.Item;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 测试boot整合es
 *
 * @author caohaiyang
 * @create 2021-02-24 上午 11:02
 */
@SpringBootTest(classes = {SpringbootEsApplication.class})
@RunWith(SpringRunner.class)
public class testES {

    @Autowired
    private ElasticsearchRestTemplate restTemplate;


    /**
     * 高亮
     */
    @Test
    public void testHighlight(){
        HighlightBuilder.Field field = new HighlightBuilder.Field("title");
        field.preTags("");
        field.postTags("");

        NativeSearchQuery query =
                new NativeSearchQueryBuilder()
                        // 排序
                        .withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC))
                        // 分页
                        .withPageable(PageRequest.of(0, 2))
                        // 搜索条件
                        .withQuery(QueryBuilders.matchQuery("title", "华为"))
                        // 设置高亮字段
                        .withHighlightFields(field)
                        .build();

        AggregatedPage<? extends Item> pageResult =
                restTemplate.queryForPage(query, Item.class, new SearchResultMapper() {
                    // 处理搜索结果,搜索的完整结果,也就是那个集合。
                    // response - 就是搜索的结果,相当于在Kibana中执行搜索的结果内容。
                    // clazz - 就是返回结果的具体类型
                    // pageable - 分页处理,就是queryForPage方法参数query中的pageable对象。
                    public <T> AggregatedPage<T> mapResults(SearchResponse response,
                                                            Class<T> clazz,
                                                            Pageable pageable) {
                        // 获取搜索的结果数据
                        SearchHit[] hits = response.getHits().getHits();
                        List<T> resultList = new ArrayList<T>();
                        for(SearchHit hit : hits){
                            // 搜索的source源
                            Map<String, Object> map = hit.getSourceAsMap();
                            Item item = new Item();
                            item.setId(map.get("id").toString());
                            item.setSellPoint(map.get("sellPoint").toString());
                            item.setPrice(Long.parseLong(map.get("price").toString()));
                            item.setNum(Integer.parseInt(map.get("num").toString()));
                            // 高亮数据处理。key - 字段名, value - 是高亮数据结果
                            Map<String, HighlightField> highlightFieldMap = hit.getHighlightFields();
                            HighlightField highlightField = highlightFieldMap.get("title");
                            if (highlightField == null){ // 没有高亮的title
                                item.setTitle(map.get("title").toString());
                            }else{ // 有高亮的title
                                item.setTitle(highlightField.getFragments()[0].toString());
                            }
                            resultList.add((T)item);
                        }
                       // 返回处理后的结果

                        return new AggregatedPageImpl<T>(
                                resultList, pageable, response.getHits().getTotalHits()
                        );
                    }

                    // 不提供实现,这个是处理每个搜索结果的方法
                    public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
                        return null;
                    }
                });

        for(Item item : pageResult.getContent()){
            System.out.println(item);
        }
    }

    /**
     * 分页和排序
     * 所有的Spring Data子工程中的分页和排序逻辑使用的都是相似的方式。
     * 根据PageRequest和Sort实现分页或排序。
     */
    @Test
    public void testPageable(){
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.matchAllQuery()
        );
        // 设置分页
        query.setPageable(PageRequest.of(0, 2));
        // 设置排序
        query.addSort(Sort.by(Sort.Direction.DESC, "price"));
        // 设置分页的同时设置排序
        // query.setPageable(PageRequest.of(0, 2, Sort.by(Sort.Direction.DESC, "price")))
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

    /**
     * 复合条件搜索
     */
    @Test
    public void testBool(){
        // 创建一个Bool搜索条件。 相当于定义 bool:{ must:[], should:[], must_not:[] }
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        List<QueryBuilder> mustList = builder.must();
        mustList.add(QueryBuilders.matchQuery("title", "华为"));
        mustList.add(QueryBuilders.rangeQuery("price").gte(300000L));
        // builder.mustNot();
        // builder.should();
        SearchQuery query = new NativeSearchQuery(builder);
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

    /**
     * 范围搜索 range
     * gte <==> 小于等于 ; gt <==> 小于
     * lte <==> 大于等于 ; lt <==> 大于
     */
    @Test
    public void testRange(){
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.rangeQuery("price").gte(500000L).lte(400000L)
        );
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

    /**
     * 词组搜索
     * 只有没有被切分的词组才能搜到结果, 例如: 华为荣耀已被切分, 则搜索不到; 而荣耀 不会被切分因此能够搜索到结果
     * 区别于短语搜索
     */
    @Test
    public void testTerm(){
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.termQuery("title", "荣耀")
        );
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

    /**
     * 短语搜索
     */
    @Test
    public void testMatchPhrase(){
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.matchPhraseQuery("title", "华为荣耀")
        );
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

    /**
     * 条件搜索
     */
    @Test
    public void testMatch(){
        SearchQuery query = new NativeSearchQuery(QueryBuilders.matchQuery("title", "华为mate40"));
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }

    /**
     * 搜索所有数据
     */
    @Test
    public void testMatchAll(){
        /*
         * SearchQuery - 是Spring Data Elasticsearch中定义的一个搜索接口
         * NativeSearchQuery - 是SearchQuery接口的实现类。
         *  构造的时候,需要提供一个QueryBuilder类型的对象,
         *  QueryBuilder是Elasticsearch的java客户端中定义的搜索条件类型。
         *
         * QueryBuilders - 是QueryBuilder类型的工具类,可以快速实现QueryBuilder类型对象的创建
         *  工具类中,提供了大量的静态方法,方法命名和DSL搜索中的条件关键字相关。
         *  如:match_all 对应 matchAllQuery()
         *  如:match 对应 matchQuery()
         *  如:range 对应 rangeQuery()
         */
        SearchQuery query = new NativeSearchQuery(
                QueryBuilders.matchAllQuery()
        );
        List<Item> itemList = restTemplate.queryForList(query, Item.class);
        for(Item item : itemList){
            System.out.println(item);
        }
    }


    /**
     * 修改文档
     * 如果是全量替换,可以使用index方法实现,只要主键在索引中存在,就是全量替换。<=>新增or批量新增操作
     * 如果是部分修改,则可以使用update实现。
     */
    @Test
    public void testUpdate() throws Exception{
        UpdateRequest request = new UpdateRequest();
        request.doc(
                XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "测试update更新数据,商品名称")
                        .endObject()
        );
        UpdateQuery updateQuery =
                new UpdateQueryBuilder()
                        .withUpdateRequest(request)
                        .withClass(Item.class)
                        .withId("20210224")
                        .build();
        restTemplate.update(updateQuery);
    }

    /**
     * 删除文档
     */
    @Test
    public void testDelete(){
        // 根据主键删除, 常用
        String result = restTemplate.delete(Item.class, "192168111");
        System.out.println(result);

        // 根据查询结果,删除查到的数据。 应用较少。
        /*DeleteQuery query = new DeleteQuery();
        query.setIndex("hrt-item");
        query.setType("item");
        query.setQuery(QueryBuilders.matchQuery("title", "沃什.伊戈.史莱姆1"));
        restTemplate.delete(query, Item.class);*/
    }

    /**
     * 批量新增
     * bulk操作
     */
    @Test
    public void testBatchInsert(){
        List<IndexQuery> queries = new ArrayList<IndexQuery>();
        Item item = new Item();
        item.setId("20210224");
        item.setTitle("IPHONE 12 手机");
        item.setSellPoint("很贵");
        item.setPrice(499900L);
        item.setNum(999);
        queries.add(new IndexQueryBuilder().withObject(item).build());
        item = new Item();
        item.setId("20210225");
        item.setTitle("华为P40照相手机");
        item.setSellPoint("可以拍月亮");
        item.setPrice(599900L);
        item.setNum(999);
        queries.add(new IndexQueryBuilder().withObject(item).build());
        item = new Item();
        item.setId("20210226");
        item.setTitle("红米k30");
        item.setSellPoint("大品牌值得信赖");
        item.setPrice(699900L);
        item.setNum(999);
        queries.add(new IndexQueryBuilder().withObject(item).build());
        // 批量新增,使用的是bulk操作。
        restTemplate.bulkIndex(queries);
    }

    /**
     * 新增数据到ES
     */
    @Test
    public void testInsert(){
        Item item = new Item();
        item.setId("19216811");
        item.setTitle("沃什.伊戈.史莱姆");
        item.setSellPoint("关于我成为史莱姆却因为铺垫太长遭人骂这档事");
        item.setPrice(996666L);
        item.setNum(233);

        //这个是构建器放入的方式
        IndexQuery indexQuery = new IndexQueryBuilder() // 创建一个IndexQuery的构建器
                                    .withObject(item) // 设置要新增的Java对象
                                    .build(); // 构建IndexQuery类型的对象。
        //这个是直接放入的方式
//        IndexQuery query = new IndexQuery();
//        query.setObject(item);
        // index逻辑,相当于使用PUT请求,实现数据的新增。
        String result = restTemplate.index(indexQuery);
        System.out.println(result);
    }

    /**
     * 删除索引
     */
    @Test
    public void deleteIndex(){
        // 扫描Item类型上的Document注解,删除对应的索引。
        boolean isDeleted = restTemplate.deleteIndex(Item.class);
        System.out.println("删除Item对应索引是否成功:"   isDeleted);
        // 直接删除对应名称的索引。
        isDeleted = restTemplate.deleteIndex("test_index3");
        System.out.println("删除default_index索引是否成功:"   isDeleted);
    }


    /**
     * 创建索引,并设置映射。
     * 需要通过两次访问实现,1、创建索引;2、设置映射。
     */
    @Test
    public void testInitIndex(){
        // 创建索引,根据类型上的Document注解创建
        boolean isCreated = restTemplate.createIndex(Item.class);
        // 设置映射,根据属性上的Field注解设置 0201
        boolean isMapped = restTemplate.putMapping(Item.class);
        System.out.println("创建索引是否成功:"   isCreated);
        System.out.println("设置映射是否成功:"   isMapped);
    }

}

0 人点赞