下载时首先看自己项目springBoot版本 需要对应
本项目使用SpringBoot2.2.5,Elasticsearch6.8.6
Elasticsearch安装和使用
下载Elasticsearch6.8.6的zip包,并解压到指定目录,下载地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-8-6
进入bin目录下安装分词器,执行命令
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.8.6/elasticsearch-analysis-ik-6.8.6.zip
运行bin目录下的elasticsearch.bat即可启动Elasticsearch
下载Kibana,作为访问Elasticsearch的客户端,请下载6.8.6版本的zip包,并解压到指定目录,下载地址:
https://artifacts.elastic.co/downloads/kibana/kibana-6.8.6-windows-x86_64.zip
运行bin目录下的kibana.bat,启动Kibana的用户界面
SpringBoot引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
使用客户端配置
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
/**
* @author Stephen
*/
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.withBasicAuth("elasticsearch","")
.build();
return RestClients.create(clientConfiguration).rest();
}
@Bean(name = "elasticsearchRestTemplate")
public ElasticsearchOperations elasticsearchTemplateCustom() {
ElasticsearchRestTemplate elasticsearchTemplate;
try {
elasticsearchTemplate = new ElasticsearchRestTemplate(elasticsearchClient());
return elasticsearchTemplate;
} catch (Exception e) {
return new ElasticsearchRestTemplate(elasticsearchClient());
}
}
}
ElasticsearchTemplate是Spring对ES的java api进行的封装,提供了大量的相关的类来完成各种各样的查询。在日常的使用中,应该说最常用的查询就是queryList方法。能够友好的进行对象关系映射
Spring Data Elasticsearch
Spring Data Elasticsearch是Spring提供的一种以Spring Data风格来操作数据存储的方式,它可以避免编写大量的样板代码。
常用注解
@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//不会进行分词建立索引的类型
}
Sping Data方式的数据操作
继承ElasticsearchRepository接口可以获得常用的数据操作方法
可以使用衍生查询
在接口中直接指定查询方法名称便可查询,无需进行实现,如商品表中有商品名称、标题和关键字,直接定义以下查询,就可以对这三个字段进行全文搜索。
/**
* 搜索查询
*
* @param name 商品名称
* @param subTitle 商品标题
* @param keywords 商品关键字
* @param page 分页信息
* @return
*/
Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);
项目使用整合Elasticsearch产品查询
EsProduct.java
import com.dandandog.framework.mapstruct.model.MapperUrl;
import com.dandandog.framework.mapstruct.model.MapperVo;
import com.google.common.collect.Lists;
import com.myelephant.module.mall.entity.enums.ProductPublishType;
import com.myelephant.module.mall.entity.enums.ProductType;
import lombok.Data;
import lombok.EqualsAndHashCode;
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.util.List;
/**
* @Author: StephenZhang
* @date: 2021-04-26 14:51
*/
@Data
@Document(indexName = "runningmom", type = "product", shards = 1, replicas = 0)
public class EsProductVo implements Serializable {
@Id
private String id;
@Field(type = FieldType.Keyword)
private String cateId;
@Field(type = FieldType.Keyword)
private String libId;
@Field(type = FieldType.Keyword, analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Object)
private ProductType type;
@Field(type = FieldType.Keyword)
private String info;
@Field(type = FieldType.Keyword)
private String infoRich;
@Field(type = FieldType.Boolean)
private boolean publish;
@Field(type = FieldType.Object)
private ProductPublishType publishType;
@Field(type = FieldType.Integer)
private int sales;
@Field(type = FieldType.Integer)
private int totalSales;
@Field(type = FieldType.Integer)
private int seq;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String keywords;
@Field(type = FieldType.Keyword)
private String videoUrl;
@Field(type = FieldType.Keyword)
private String applicable;
@Field(type = FieldType.Keyword)
private String budget;
}
实现ElasticsearchRepository
import com.myelephant.projects.elasticsearch.entity.EsProductVo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;
/**
* @Author: StephenZhang
* @date: 2021-04-26 15:08
*/
@Component
public interface EsProductRepository extends ElasticsearchRepository<EsProductVo, String> {
/**
* 搜索查询
*
* @param id 商品名称
* @return EsProductVo
*/
EsProductVo findEsProductVoById(String id);
/**
* 搜索查询
*
* @param name 商品关键字
* @param keywords 商品关键字
* @param pageable 当前页
* @return Page<EsProductVo>
*/
Page<EsProductVo> findByNameLikeOrKeywordsLike(String name, String keywords, Pageable pageable);
}
基本操作可以使用
@Resource private EsProductRepository repository;
复杂查询API可以使用
@Resource
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@GetMapping("/page")
@ApiOperation(value = "分页获取商品")
@ApiImplicitParams({
@ApiImplicitParam(name = "page", required = true, dataType = "Integer", value = "当前页"),
@ApiImplicitParam(name = "size", required = true, dataType = "Integer", value = "分页大小"),
@ApiImplicitParam(name = "search", dataType = "String", value = "关键字或者名称查询")
})
@ApiResponse(code = 200, message = "操作成功", response = String.class)
public ApiResult<PageResult<EsProductVo>> getEsProdPage(@RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int size,
@RequestParam(required = false) String search) {
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
//查询条件
.withQuery(QueryBuilders.multiMatchQuery(search, "name", "keywords"))
//分页
.withPageable(PageRequest.of(page - 1, size))
//排序
.withSort(SortBuilders.fieldSort("seq").order(SortOrder.DESC))
//高亮字段显示
.withHighlightFields(new HighlightBuilder.Field(search))
.build();
Page<EsProductVo> esVos = elasticsearchRestTemplate.queryForPage(nativeSearchQuery, EsProductVo.class);
PageResult<EsProductVo> iPage =
new PageResult<>(esVos.getNumber() + 1, esVos.getSize(), esVos.getTotalElements(), esVos.getContent());
LOGGER.info("已完成");
return success(iPage);
}