Spring Data Elasticsearch简单入门

Spring Data Elasticsearch 简介

SpringData项目下的子项目 用于访问Elasticsearch

Spring Data Elasticsearch常用注解

@Document

指定实体类和索引对应关系s

属性:

  • indexName:索引名称
  • shards: 主分片数量。从ES 7开始默认1
  • replicas:复制分片数量。从ES 7开始默认1

@Id

指定主键

@Field

指定普通属性

属性:

  • name :字段类型。默认为当前属性名

  • type: 对应Elasticsearch中属性类型,默认是FieldType.Auto

  • analyzer: 分词器名称,必须type=Text才有效。默认为standard

  • index: 是否创建索引。默认true

代码示例

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "item_index", shards = 1, replicas = 0)
public class Item implements Serializable {
    /**
     * @Id Spring Data 框架的通用注解,用于描述一个主键属性
     *     在Spring Data Elasticsearch 框架中,读写操作id字段的首,会在_source中记录同值数据
     *
     * @Field 描述属性和索引字段映射
     *  - name 字段类型。默认为当前属性名
     *  - type 字段类型。默认是FieldType.Auto
     *  - analyzer 分词器名称,必须type=Text才有效。默认为standard
     *  - index 是否创建索引。默认true
     */
    @Id
    @Field(name = "id", type = FieldType.Keyword)
    private String id;//商品id

    @Field(name = "title", type = FieldType.Text, analyzer = "ik_max_word")
    private String title;//商品标题

    @Field(name = "item_desc", type = FieldType.Text, analyzer = "ik_smart")
    private String itemDesc;//商品描述

    @Field(name = "sellPoint", type = FieldType.Text, analyzer = "ik_smart")
    private String sellPoint; //商品卖点

    @Field(name = "price", type = FieldType.Long)
    private Long price;//价格

    @Field(name = "num", type = FieldType.Integer, index = false)
    private int num;/*库存*/
}

Spring Data Elasticsearch配置文件

# 支持集群化配置。多个节点的地址用逗号分隔
spring:
  elasticsearch:
    rest:
      uris: http://192.168.190.128:9200 # 集群节点路径

#  data:
#    elasticsearch:
#      cluster-name: xxx # 集群名称
#      cluster-nodes: 192.168.137.128:9300,ip:9300

Spring Data Elasticsearch访问示例

  @Autowired
  private ElasticsearchRestTemplate template;

创建索引

/**
     * 创建索引
     * PUT my_first_index
     * 创建索引并映射
     * PUT my_first_index2
     * { "mappings": {"properties": {
     *      "id":{"type":"long","index":"true"},
     *      "title":{"type":"text","index":"true","analyzer":"ik_max_word" }
     *   }
     * }
     */
    @Test
    public void createIndex() {
        //获取索引操作对象
        IndexOperations indexOps = template.indexOps(Item.class);
        //创建索引
        boolean isCreated = indexOps.create();
        System.out.println(isCreated ? "创建成功" : "创建失败");
        /*创建映射 */
        boolean isMapped = indexOps.putMapping(indexOps.createMapping());
        System.out.println(isMapped ? "映射配置成功" : "映射配置失败");
    }

删除索引

/**
     * 删除索引
     * 对应: DELETE /my_first_index2
     */
    @Test
    public void deleteIndex() {
        boolean isDeleted = template.indexOps(Item.class).delete();
        System.out.println(isDeleted ? "删除成功" : "删除失败");
    }

添加数据

/**
     * 新增文档
     * 对应:
     * POST test_search/_bulk
     * { "index": {}}
     * { "dname" : "Sales Department", "ename" : "张三", "eage":20, "hiredate" : "2019-01-01", "gender" : "男性" }
     * { "index": {}}
     * { "dname" : "Sales Department", "ename" : "李四", "eage":21, "hiredate" : "2019-02-01", "gender" : "男性"
     * <p>
     * 全量替换使用save()方法
     */
    @Test
    public void insertDoc() {
        Item item1 = new Item("001", "华为P40", "照相机很牛,价格有点贵",
                "国产高端机", 489900L, 100);
        Item item2 = new Item("002", "荣耀Play 3T", "玩游戏的手机,扩展配置为0,就是RAM大",
                "很便宜", 119900L, 100);
        Item item3 = new Item("003", "红米5", "冬天不怕冷,暖手暖脚神器,容易爆炸",
                "国产网红产品1号", 289900L, 100);
        Item item4 = new Item("004", "IPhone 12", "贵,曾经很贵",
                "品牌象征", 689900L, 100);
        Item item5 = new Item("005", "华为P30", "照相机很牛,价格有点贵",
                "国产中端机", 389900L, 100);
        Item item6 = new Item("006", "荣耀Play", "玩游戏的手机,扩展配置为0,就是RAM大",
                "很便宜", 119900L, 100);
        Item item7 = new Item("007", "红米4", "冬天不怕冷,暖手暖脚神器,容易爆炸",
                "国产网红产品1号", 189900L, 100);
        Item item8 = new Item("008", "IPhone 11", "贵,曾经很贵",
                "品牌象征", 589900L, 100);
        template.save(item1);
        template.save(item2, item3, item4, item5, item6, item7, item8);
        System.out.println("添加数据结束");
    }

修改数据

/**
     * 修改数据
     * 对应: POST my_first_index/_update/4
     * {"doc":{"name":"赵六"}}
     */
    @Test
    public void updateDoC() {
        UpdateQuery updateQuery = UpdateQuery.builder("001")
                .withDocument(Document.create().append("num", 200))
                .build();
        UpdateResponse updateResponse =
                template.update(updateQuery, IndexCoordinates.of("item_index"));
        System.out.println(updateResponse.getResult());

    }

删除数据

 /**
     * 删除
     * 对应: DELETE my_first_index/_doc/3
     */
    @Test
    public void deleteDoc() {
        /*Item item = new Item("009", "IPhone 11", "贵,曾经很贵",
                "品牌象征", 589900L, 100);
        template.save(item);*/

        String delete = template.delete("009", Item.class);
        System.out.println(delete);
    }

查询数据


    /**
     * 主键查询
     * 对应: GET my_first_index/_doc/1
     */
    @Test
    public void searchById() {
        Item item = template.get("001", Item.class);
        System.out.println(item);
    }
/**
     * 全字段查询
     * 对应: GET /索引/_search?q=xxx
     * <p>
     * NativeSearchQuery - spring data elasticsearch提供的一个查询对象
     * NativeSearchQueryBuilder - 是NativeSearchQuery类型的构建器。
     * - withQuery(QueryBuilder queryBuilder) - 提供搜索条件
     * - build() - 构建一个NativeSearchQuery类型的对象。
     * <p>
     * QueryBuilder - Elasticsearch Java 客户端API提供的搜索条件类型
     * 有若干实现类型。对应不同的搜索方案。实现类型的命名有一定的规则,和搜索方案相关。
     * 如:query string搜索。 对应的实现是QueryStringQueryBuilder
     * DSL中的match搜索。 对应的实现是MatchQueryBuilder
     */
    @Test
    public void searchQueryString() {
        NativeSearchQuery query =
                new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.queryStringQuery("贵"))
                        .build();
        SearchHits<Item> searchHits = template.search(query, Item.class);
        System.out.println("是否有查询结果 :" + searchHits.isEmpty());
        System.out.println("数据条数 :" + searchHits.getTotalHits());
        System.out.println("最大相关度分数 max_score :" + searchHits.getMaxScore());

        searchHits.forEach(hit -> {
            System.out.println(hit.getContent());
        });
    }
 /**
     * math_all 查询所有数据
     * 对应: GET test_search/_search
     * {"query" : { "match_all" : {} }}
     */
    @Test
    public void mathAll() {
        SearchHits<Item> searchHits = template.search(
                new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery()).build()
                , Item.class
        );

        searchHits.forEach(hit -> {
            System.out.println(hit.getContent());
        });
    }

    /**
     * match
     * GET test_search/_search
     * {"query":{ "match":{"dname":"Sales"} } }
     */
    @Test
    public void match() {
        SearchHits<Item> searchHits =
                template.search(
                        new NativeSearchQueryBuilder()
                                .withQuery(QueryBuilders.matchQuery("item_desc", "照相机很牛,价格挺贵")).build(),
                        Item.class
                );
        searchHits.forEach(hit -> {
            System.out.println(hit.getContent());
        });
    }
/**
     * match_phrase
     * GET item_index/_search
     * { "query": {"match_phrase": {"item_desc": "价格"}}}
     */
    @Test
    public void matchPhrase() {
        SearchHits<Item> searchHits =
                template.search(
                        new NativeSearchQueryBuilder()
                                .withQuery(QueryBuilders.matchPhraseQuery("item_desc", "价格")).build(),
                        Item.class
                );

        searchHits.forEach(hit -> {
            System.out.println(hit.getContent());
        });
    }

    /**
     * range
     */
    @Test
    public void matchAll() {
        SearchHits<Item> searchHits =
                template.search(
                        new NativeSearchQueryBuilder().
                                withQuery(QueryBuilders.rangeQuery("price")
                                        .gte(200000L)
                                        .lte(500000L))
                                .build(),
                        Item.class
                );

        searchHits.forEach(hit -> {
            System.out.println(hit.getContent());
        });
    }
 @Test
    public void boolS() {
        /*
         * BoolQueryBuilder中包含3个集合。分别是:
         *  List<QueryBuilder> must
         *  List<QueryBuilder> mustNot
         *  List<QueryBuilder> should
         * 提供了3个获取结合的方法
         *  must()
         *  mustNot()
         *  should()
         * 提供了3个直接向指定集合中保存QueryBuilder对象的方法
         *  must(QueryBuilder b) { must().add(b); }
         *  mustNot(QueryBuilder)
         *  should(QueryBuilder)
         */

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.rangeQuery("price").lte(500000L));
        queryBuilder.must(QueryBuilders.matchQuery("title", "华为"));
        NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();

        SearchHits<Item> searchHits = template.search(query, Item.class);
        searchHits.forEach(hit -> {
            System.out.println(hit.getContent());
        });
    }

分页和排序


    /**
     * 排序和分页
     */
    @Test
    public void sortAndPageable() {
        SearchHits<Item> searchHits = template.search(
                new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.matchAllQuery())
                        .withPageable(
                                PageRequest.of(0, 3,
                                        Sort.by(Sort.Order.asc("price"), Sort.Order.desc("id"))
                                        //Sort.by(Sort.Direction.ASC, "price")
                                )
                        ).build()
                , Item.class
        );

        searchHits.forEach(hit -> {
            System.out.println(hit.getContent());
        });
    }

高亮数据


    /**
     * 高亮
     */
    @Test
    public void highlight() {
        //创建高亮字段
        HighlightBuilder.Field field1 = new HighlightBuilder.Field("title");
        field1.numOfFragments(1);
        field1.fragmentSize(3);
        //高亮前缀
        field1.preTags("<span style='color:red'>");
        //高亮后缀
        field1.postTags("</span>");
        NativeSearchQuery query =
                new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.matchQuery("title", "华为"))
                        .withHighlightFields(field1) // 设置若干高亮字段
                        .build();

        SearchHits<Item> searchHits = template.search(query, Item.class);
        List<Item> itemList = new ArrayList<>();
        searchHits.forEach(hit -> {
            Item item = hit.getContent();
            List<String> highlight = hit.getHighlightField("title");
            if (null != highlight && highlight.size() > 0) {
                item.setTitle(highlight.get(0));
            }
            itemList.add(item);
        });
        itemList.forEach(System.out::println);
    }

    @Test
    public void highlight2() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchQuery("title", "华为"));
        //排序
        nativeSearchQuery.addSort(Sort.by(Sort.Direction.DESC, "price"));
        //分页
        nativeSearchQuery.setPageable(PageRequest.of(0, 2));

        //设置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();

        //设置高亮属性
        highlightBuilder.field("title");//.numOfFragments(2).fragmentSize(3);
        //高亮前缀
        highlightBuilder.preTags("<span style='color:red'>");
        // 高亮内容后缀
        highlightBuilder.postTags("</span>");

        //高亮查询
        HighlightQuery highlightQuery = new HighlightQuery(highlightBuilder);
        //应用高亮
        nativeSearchQuery.setHighlightQuery(highlightQuery);

        SearchHits<Item> searchHits = template.search(nativeSearchQuery, Item.class);

        List<SearchHit<Item>> highlights = searchHits.getSearchHits();
        List<Item> itemList = new ArrayList<>();
        highlights.forEach(hit -> {
            Item item = hit.getContent();
            String title = hit.getHighlightField("title").get(0);
            item.setTitle(title);
            itemList.add(item);
        });

        itemList.forEach(System.out::println);
    }
}

Spring Data Elasticsearch依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.2.RELEASE</version>
    <relativePath/>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
</dependencies>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值