springboot整合Elasticsearch - Go语言中文社区

springboot整合Elasticsearch


1.简介

Elasticsearch 是一个分布式、可扩展、实时的搜索与数据分析引擎。 它能从项目一开始就赋予你的数据以搜索、分析和探索的能力,可用于实现全文搜索和实时数据统计。

2.下载与安装

可以去官方网站去进行下载,下载好之后解压运行即可

3.Spring Data Elasticsearch

Spring Data Elasticsearch是Spring提供的一种以Spring Data风格来操作数据存储的方式,它可以避免编写大量的样板代码。

4.常用注解

@Document
//标示映射到Elasticsearch文档上的领域对象
public @interface Document{
//索引库名次,mysql中数据库的概念
String indexName();
//文档类型,mysql中表的概念
String type() default "";
//默认分片数
short shards () default 5;  
//默认副本数量
short replicas() default 1;

@Id
//表示是文档的id,文档可以认为是mysql中表行的概念
public @interface Id{
}
@Field
public @interface Field {
    //文档中字段的类型
	FieldType type() default FieldType.Auto;
    //是否建立倒排索引
	boolean index() default true;
    //是否进行存储
	boolean store() default false;
    //分词器名次
	String analyzer() default "";
}
//为文档自动指定元数据类型
public enum FieldType {
	Text,//会进行分词并建了索引的字符类型
	Integer,
	Long,
	Date,
	Float,
	Double,
	Boolean,
	Object,
	Auto,//自动判断字段类型
	Nested,//嵌套对象类型
	Ip,
	Attachment,
	Keyword//不会进行分词建立索引的类型
}

5.编码

EsProductController

package com.tuanzi.controller;

import com.tuanzi.common.api.CommonPage;
import com.tuanzi.common.api.CommonResult;
import com.tuanzi.nosql.elasticsearch.document.EsProduct;
import com.tuanzi.service.EsProductService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 搜索商品管理Controller
 * @author 团子
 * @date 2019-11-03 09:45
 */
@Controller
@Api(tags = "EsProductController", description = "搜索商品管理")
@RequestMapping("/esProduct")
public class EsProductController {

    private static final Logger logger  = LoggerFactory.getLogger(EsProductController.class);

    @Autowired
    private EsProductService esProductService;

    @ApiOperation(value = "导入所有数据库中商品到ES")
    @RequestMapping(value = "/importAll", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<Integer> importAllList() {
        int count = esProductService.importAll();
        return CommonResult.success(count);
    }

    @ApiOperation(value = "根据id删除商品")
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<Object> delete(@PathVariable Long id) {
        esProductService.delete(id);
        return CommonResult.success(null);
    }

    @ApiOperation(value = "根据id批量删除商品")
    @RequestMapping(value = "/delete/batch", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<Object> delete(@RequestParam("ids") List<Long> ids) {
        esProductService.delete(ids);
        return CommonResult.success(null);
    }

    @ApiOperation(value = "根据id创建商品")
    @RequestMapping(value = "/create/{id}", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult< EsProduct > create(@PathVariable Long id) {
        EsProduct esProduct = esProductService.create(id);
        if (esProduct != null) {
            return CommonResult.success(esProduct);
        } else {
            return CommonResult.failed();
        }
    }

    @ApiOperation(value = "简单搜索")
    @RequestMapping(value = "/search/simple", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult< CommonPage<EsProduct> > search(@RequestParam(required = false) String keyword,
                                                        @RequestParam(required = false, defaultValue = "0") Integer pageNum,
                                                        @RequestParam(required = false, defaultValue = "5") Integer pageSize) {
       
        Page<EsProduct> esProductPage = esProductService.search(keyword, pageNum, pageSize);
        return CommonResult.success(CommonPage.restPage(esProductPage));
    }

}

EsProductService

package com.tuanzi.service;

import com.tuanzi.nosql.elasticsearch.document.EsProduct;
import org.springframework.data.domain.Page;

import java.util.List;

/**
 * 商品搜索管理Service
 * @author 团子
 * @date 2019-11-03 09:38
 */

public interface EsProductService {
    /**
     * 从数据库中导入所有商品到ES
     */
    int importAll();

    /**
     * 根据id删除商品
     */
    void delete(Long id);

    /**
     * 根据id创建商品
     */
    EsProduct create(Long id);

    /**
     * 批量删除商品
     */
    void delete(List<Long> ids);

    /**
     * 根据关键字搜索名称或者副标题
     */
    Page< EsProduct > search(String keyword, Integer pageNum, Integer pageSize);

}

EsProductServiceImpl

package com.tuanzi.service.impl;

import com.tuanzi.dao.EsProductDao;
import com.tuanzi.nosql.elasticsearch.document.EsProduct;
import com.tuanzi.nosql.elasticsearch.repository.EsProductRepository;
import com.tuanzi.service.EsProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 商品搜索管理Service实现类
 * @author 团子
 * @date 2019-11-03 09:40
 */
@Service
public class EsProductServiceImpl implements EsProductService {
    private static final Logger logger = LoggerFactory.getLogger(EsProductServiceImpl.class);
    @Autowired
    private EsProductDao productDao;
    @Autowired
    private EsProductRepository productRepository;

    @Override
    public int importAll() {
        List<EsProduct> esProductList = productDao.getAllEsProductList(null);
        Iterable<EsProduct> esProductIterable = productRepository.saveAll(esProductList);
        Iterator<EsProduct> iterator = esProductIterable.iterator();
        int result = 0;
        while (iterator.hasNext()) {
            result++;
            iterator.next();
        }
        return result;
    }

    @Override
    public void delete(Long id) {
        productRepository.deleteById(id);
    }

    @Override
    public EsProduct create(Long id) {
        EsProduct result = null;
        List<EsProduct> esProductList = productDao.getAllEsProductList(id);
        if (esProductList.size() > 0) {
            EsProduct esProduct = esProductList.get(0);
            result = productRepository.save(esProduct);
        }
        return result;
    }

    @Override
    public void delete(List<Long> ids) {
        if (!CollectionUtils.isEmpty(ids)) {
            List<EsProduct> esProductList = new ArrayList<>();
            for (Long id : ids) {
                EsProduct esProduct = new EsProduct();
                esProduct.setId(id);
                esProductList.add(esProduct);
            }
            productRepository.deleteAll(esProductList);
        }
    }

    @Override
    public Page< EsProduct > search(String keyword, Integer pageNum, Integer pageSize) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        return productRepository.findByNameOrSubTitleOrKeywords(keyword, keyword, keyword, pageable);
    }

}

EsProductDao

package com.tuanzi.dao;

import com.tuanzi.nosql.elasticsearch.document.EsProduct;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 搜索系统中的商品管理自定义Dao
 * @author 团子
 * @date 2019-11-03 09:43
 */
@Mapper
@Repository
public interface EsProductDao {

    List< EsProduct > getAllEsProductList(@Param("id") Long id);

}

EsProductDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tuanzi.dao.EsProductDao">
    <resultMap id="esProductListMap" type="com.tuanzi.nosql.elasticsearch.document.EsProduct" autoMapping="true">
        <id column="id" jdbcType="BIGINT" property="id" />
        <collection property="attrValueList" columnPrefix="attr_" ofType="com.tuanzi.nosql.elasticsearch.document.EsProductAttributeValue">
            <id column="id" property="id" jdbcType="BIGINT"/>
            <result column="product_attribute_id" property="productAttributeId" jdbcType="BIGINT"/>
            <result column="value" property="value" jdbcType="VARCHAR"/>
            <result column="type" property="type"/>
            <result column="name" property="name"/>
        </collection>
    </resultMap>
    <select id="getAllEsProductList" resultMap="esProductListMap">
        SELECT
        p.id id,
        p.product_sn productSn,
        p.brand_id brandId,
        p.brand_name brandName,
        p.product_category_id productCategoryId,
        p.product_category_name productCategoryName,
        p.NAME NAME,
        p.sub_title subTitle,
        p.price price,
        p.sale sale,
        p.new_status newStatus,
        p.recommand_status recommandStatus,
        p.stock stock,
        p.promotion_type promotionType,
        p.keywords keywords,
        p.sort sort,
        p.description,
        pav.id attr_id,
        pav.VALUE attr_value,
        pav.product_attribute_id attr_product_attribute_id,
        pa.type attr_type,
        pa.NAME attr_name
        FROM
        pms_product p
        LEFT JOIN pms_product_attribute_value pav ON p.id = pav.product_id
        LEFT JOIN pms_product_attribute pa ON pav.product_attribute_id = pa.id
        WHERE
        delete_status = 0
        AND publish_status = 1
        <if test="id!=null">
            and p.id=#{id}
        </if>
    </select>
</mapper>

添加EsProductRepository接口用于操作Elasticsearch
继承ElasticsearchRepository接口,这样就拥有了一些基本的Elasticsearch数据操作方法,同时定义了一个衍生查询方法。

package com.tuanzi.nosql.elasticsearch.repository;

import com.tuanzi.nosql.elasticsearch.document.EsProduct;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

/**
 * 商品ES操作类
 * @author 团子
 * @date 2019-11-03 09:53
 */
public interface EsProductRepository extends ElasticsearchRepository< EsProduct, Long> {
    /**
     * 搜索查询
     *
     * @param name              商品名称
     * @param subTitle          商品标题
     * @param keywords          商品关键字
     * @param page              分页信息
     * @return
     */
    Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);

}

添加商品文档对象EsProduct
不需要中文分词的字段设置成@Field(type = FieldType.Keyword)类型,需要中文分词的设置成@Field(analyzer = “ikmaxword”,type = FieldType.Text)类型。

package com.tuanzi.nosql.elasticsearch.document;

import lombok.Data;
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 java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

/**
 * 搜索中的商品信息
 * @author 团子
 * @date 2019-11-03 09:53
 */
@Data
@Document(indexName = "pms", type = "product",shards = 1,replicas = 0)
public class EsProduct implements Serializable {
    private static final long serialVersionUID = -1L;
    @Id
    private Long id;
    @Field(type = FieldType.Keyword)
    private String productSn;
    private Long brandId;
    @Field(type = FieldType.Keyword)
    private String brandName;
    private Long productCategoryId;
    @Field(type = FieldType.Keyword)
    private String productCategoryName;
    private String description;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String name;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String subTitle;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String keywords;
    private BigDecimal price;
    private Integer sale;
    private Integer newStatus;
    private Integer recommandStatus;
    private Integer stock;
    private Integer promotionType;
    private Integer sort;
    @Field(type =FieldType.Nested)
    private List<EsProductAttributeValue> attrValueList;

}

EsProductAttributeValue

package com.tuanzi.nosql.elasticsearch.document;

import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.io.Serializable;
/**
 * 搜索中的商品属性信息
 * @author 团子
 * @date 2019-11-03 09:53
 */
@Data
public class EsProductAttributeValue implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;
    private Long productAttributeId;
    //属性值
    @Field(type = FieldType.Keyword)
    private String value;
    //属性参数:0->规格;1->参数
    private Integer type;
    //属性名称
    @Field(type=FieldType.Keyword)
    private String name;

}

6.进行接口测试

首先启动Elasticsearch
将数据库中数据导入到Elasticsearch

在这里插入图片描述
在这里插入图片描述
我们用Kibana,作为访问Elasticsearch的客户端,查询一下
发现数据已经全部导入进去了
在这里插入图片描述

进行简单搜索
在这里插入图片描述

在这里插入图片描述

7.下载地址

Elasticsearch6.2.2
Kibana
版本须一致都为6.2.2版本的zip包
*安装中文分词插件,在elasticsearch-6.2.2bin目录下执行以下命令:elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.2/elasticsearch-a

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_42370891/article/details/102883157
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-12-12 00:26:17
  • 阅读 ( 1343 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢