springboot springdata 整合es

实体类

package com.fwz.tproject.bean;

import java.io.Serializable;
import java.math.BigDecimal;

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;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Document(indexName = "product_index", shards = 3, replicas = 1)
@Accessors(chain = true)
public class Product implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Id
    Long id;
    @Field(type = FieldType.Text, analyzer = "ik_smart")
    String title; // 标题
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    String description; // 描述
    @Field(type = FieldType.Keyword)
    String category;// 分类
    @Field(type = FieldType.Keyword)
    String brand; // 品牌
    @Field(type = FieldType.Double)
    BigDecimal price; // 价格
    @Field(index = false, type = FieldType.Keyword)
    String images; // 图片地址
}

controller

package com.fwz.tproject.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fwz.tproject.bean.Product;
import com.fwz.tproject.serviceImpl.SpringESService;

/**
 * r
 * 
 * @author 冯文哲
 * @version 2018-06-11
 */
@RestController
@RequestMapping(value = "/ses")
public class SpringESController {

    @Autowired
    private SpringESService springESService;

    @RequestMapping(value = "/cindex")
    public Boolean testCreate() { //
        return springESService.createIndex();
    }

    @RequestMapping(value = "/search")
    public SearchHits<Product> search() { //
        return springESService.search();
    }

}

Service

package com.fwz.tproject.serviceImpl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.SearchHitsIterator;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.AliasQuery;
import org.springframework.data.elasticsearch.core.query.BulkOptions;
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
import org.springframework.data.util.CloseableIterator;

import com.fwz.tproject.bean.Product;
import com.fwz.tproject.service.ElasticSearchUtils;
import com.fwz.tproject.service.IdGeneratorSnowflake;
import com.fwz.tproject.service.Serv;

@SpringBootTest
class SpringESServiceTest implements Serv {

    Logger logger = LoggerFactory.getLogger(ElasticSearchUtils.class.getName());
    @Autowired
    public ElasticsearchOperations elasticsearchOperations;
    @Autowired
    public IdGeneratorSnowflake f;

    /**
     * 创建索引
     * 
     * @author fwzz
     * @version 创建时间:2021年1月29日 下午5:53:58
     *
     */
    @Test
    void testCreateIndex() {
        IndexOperations indexOperations = elasticsearchOperations.indexOps(Product.class);
        Document d = indexOperations.createMapping(Product.class);
        logger.info(d.toJson());
        logger.info("start=====================================");

        Boolean b = indexOperations.create();
        logger.info("end=====================================");
        indexOperations.putMapping(d);
        logger.info(b.toString());

    }

    /**
     * 设置别名
     * 
     * @author fwzz
     * @version 创建时间:2021年1月29日 下午5:54:05
     *
     */
    @Test
    void testSetAlias() {

        IndexOperations indexOperations = elasticsearchOperations.indexOps(Product.class);
        // 设置别名
        AliasQuery aq = new AliasQuery("my_product");
        indexOperations.addAlias(aq);
    }

    /**
     * 删除别名
     * 
     * @author fwzz
     * @version 创建时间:2021年1月29日 下午5:54:05
     *
     */
    @Test
    void testRemoveAlias() {

        IndexOperations indexOperations = elasticsearchOperations.indexOps(Product.class);
        // 删除别名
        AliasQuery aq = new AliasQuery("my_product");
        indexOperations.removeAlias(aq);
    }

    /**
     * 单条数据插入
     * 
     * @author fwzz
     * @version 创建时间:2021年1月29日 下午7:48:39
     *
     */
    @Test
    void testSaveDocuments() {
        Product product = new Product().setBrand(String.valueOf(32 / 5)).setCategory(String.valueOf(65 / 16))
                .setDescription("红色的轿车").setPrice(new BigDecimal(568)).setTitle("比亚迪轿车")
                .setImages("http://www.xymapp.cn").setId(f.snowflakeId());
        IndexQuery indexQuery = new IndexQueryBuilder().withId(product.getId().toString()).withObject(product).build();
        elasticsearchOperations.index(indexQuery, IndexCoordinates.of("my_product"));
    }

    /**
     * 单条数据插入
     * 
     * @author fwzz
     * @version 创建时间:2021年1月29日 下午7:48:39
     *
     */
    @Test
    void testSave() {
        Product product = new Product().setBrand(String.valueOf(32 / 5)).setCategory(String.valueOf(65 / 16))
                .setDescription("红色的轿车").setPrice(new BigDecimal(568)).setTitle("比亚迪轿车")
                .setImages("http://www.xymapp.cn").setId(f.snowflakeId());
        System.out.println(product.getId());
        elasticsearchOperations.save(product);
    }

    /**
     * 测试修改
     * 
     * @author fwzz
     * @version 创建时间:2021年1月29日 下午7:48:39
     *
     */
    @Test
    void testUpdate() {
        Product product = new Product().setId(1355127539135283200L).setBrand("update brand");
        elasticsearchOperations.save(product);
    }

    /**
     * 测试查询
     * 
     * @author fwzz
     * @version 创建时间:2021年1月29日 下午7:48:39
     *
     */
    @Test
    void testSearch() {
        // 分词字段/高亮字段
        String fieId = "title";
        String fieId1 = "description";
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // match类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("比亚迪红色", fieId, fieId1);
        multiMatchQueryBuilder.type(MultiMatchQueryBuilder.Type.BEST_FIELDS);
        multiMatchQueryBuilder.tieBreaker(0.3F);
        // 应该匹配的分词的最少数量
        multiMatchQueryBuilder.minimumShouldMatch("30%");
        queryBuilder.withQuery(multiMatchQueryBuilder);
        // 排序
        queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));

        HighlightBuilder.Field allHighLight = new HighlightBuilder.Field(fieId).preTags("<span style=\"color:red\">")
                .postTags("</span>").requireFieldMatch(false);

        HighlightBuilder.Field allHighLight1 = new HighlightBuilder.Field(fieId1).requireFieldMatch(false)
                .preTags("<span style=\"color:red\">").postTags("</span>");

        HighlightBuilder.Field[] ary = new HighlightBuilder.Field[2];
        ary[0] = allHighLight;
        ary[1] = allHighLight1;
        queryBuilder.withHighlightFields(ary);//高亮
        queryBuilder.addAggregation(AggregationBuilders.terms("4").field("category"));//聚合
        queryBuilder.withPageable(PageRequest.of(0, 10));//分页

        SearchHits<Product> hit = elasticsearchOperations.search(queryBuilder.build(), Product.class);
        logger.info(String.valueOf(hit.getSearchHits().size()));

    }

    /**
     * 批量插入
     * 
     * @author fwzz
     * @version 创建时间:2021年1月29日 下午7:48:39
     *
     */
    @Test
    void testPutBulkDocuments() {
        List<IndexQuery> queries = new ArrayList<IndexQuery>();
        for (int i = 0; i < 100; i++) {
            Product p = new Product();
            p.setBrand(String.valueOf(i / 5)).setCategory(String.valueOf(i / 16)).setDescription("红色的轿车")
                    .setPrice(new BigDecimal(568)).setTitle("比亚迪轿车").setImages("http://www.xymapp.cn")
                    .setId(f.snowflakeId());
            IndexQuery q = new IndexQueryBuilder().withId(p.getId().toString()).withObject(p).build();

            queries.add(q);
        }

        elasticsearchOperations.bulkIndex(queries, IndexCoordinates.of("my_product"));
        // elasticsearchOperations.bulkIndex(queries, index);
    }

}

ID工具类:

package com.fwz.tproject.testfunction.service;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;

@Component
public class IdGeneratorSnowflake {
    private long workerId = 0;
    private long datacenterId = 1;
    private Snowflake snowflake = IdUtil.createSnowflake(workerId, datacenterId);

    private static final Logger log = LoggerFactory.getLogger(IdGeneratorSnowflake.class.getName());

    // 依赖注入完成后执行该方法,进行一些初始化工作
    @PostConstruct
    public void init() {
        try {
            workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr());
            log.info("当前机器的workerId: {}", workerId);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("当前机器的workerId获取失败", e);
            // 释放ID
            workerId = NetUtil.getLocalhostStr().hashCode();
        }
    }

    // 使用默认机房号获取ID
    public synchronized long snowflakeId() {
        return snowflake.nextId();
    }

    // 自己制定机房号获取ID
    public synchronized long snowflakeId(long workerId, long datacenterId) {
        Snowflake snowflake = IdUtil.createSnowflake(workerId, datacenterId);

        return snowflake.nextId();
    }

    /**
     * 生成的是不带-的字符审,类似于: 73a64edf935d4952a287739a66f96e06
     * 
     * @return
     */
    public String simpleUUID() {
        return IdUtil.simpleUUID();
    }

    /**
     * 生成的UUID是带-的字符串,类似于: b12b6401-6f9c-4351-b2b6-d8afc9ab9272
     * 
     * @return
     */
    public String randomUUID() {
        return IdUtil.randomUUID();
    }

    public static void main(String[] args) {
        IdGeneratorSnowflake f = new IdGeneratorSnowflake();
        for (int i = 0; i < 1000; i++) {

            System.out.println(f.snowflakeId(0, 0));
        }

    }
}

要使用工具类pom.xml需加入依赖:

 <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-captcha</artifactId>
            <version>5.2.0</version>
        </dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

 

posted @ 2021-01-29 21:13  陈扬天  阅读(683)  评论(0编辑  收藏  举报