1.引入maven包
<!-- el-search-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
2.配置yml文件
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 127.0.0.1:9300
3.分页搜索使用
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Setter;
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.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Document(indexName = "skus01", type = "docs", shards = 5, replicas = 1)
public class SearchSku {
@Id
private Integer id; // skuId
@Field(type = FieldType.Keyword, index = false)//不分词不索引只存储
private String logo;//图片地址
@Field(type = FieldType.Text, analyzer = "ik_max_word")// 分词索引存储
private String sku_name;//sku名字
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String all; //用于关键字搜索, 所有需要被搜索的信息,包含标题,分类,甚至品牌
// @Field(type = FieldType.Date)
// private Date on_sale_time;//上架时间--用于时间排序
@Field(type = FieldType.Long)
private Long on_sale_time;//上架时间--用于时间排序
//品牌编号
@Field(type = FieldType.Integer)
private Integer brand_id;
// 分类id
@Field(type = FieldType.Integer)
private Integer cat3_id;
//规格列表 : {"机身颜色":"白色","内存":"3GB","机身存储":"16GB"}
private Map<String, Object> specs;// 可搜索的规格参数,key是参数名,值是参数值
@Field(type = FieldType.Double)
private Double price;// 价格
@Field(type = FieldType.Text)
private String spu_name;
@Field(type = FieldType.Integer)
// 库存量
private Integer stock;
@Field(type = FieldType.Text)
private String description;
@Field(type = FieldType.Text)
private String packages;//规格与包装
@Field(type = FieldType.Text)
private String aftersale;//售后保障
//private String midlogo;
//评价数
@Field(type = FieldType.Integer)
private Integer comment_count;
// 销量
@Field(type = FieldType.Integer)
private Integer seller_count;
}
关于注解的用法:Elasticsearch搜索引擎一些参数含义和用法_瑶山的博客-优快云博客
import com.czxy.vo.SearchSku;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@FeignClient(name="web-service")
@RequestMapping
public interface SkuClient {
@GetMapping("/esData")
public ResponseEntity<List<SearchSku>> findESData();
}
feign 调用远程服务,用来查询所有商品 。
import com.czxy.vo.SearchSku;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface SkuRepository extends ElasticsearchRepository<SearchSku,Integer> {
}
import com.czxy.client.SkuClient;
import com.czxy.dao.SkuRepository;
import com.czxy.vo.ReturnSku;
import com.czxy.vo.SearchResult;
import com.czxy.vo.SearchSku;
import com.czxy.vo.SkuSearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class SkuSearchService {
@Autowired
private SkuRepository skuRepository;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Autowired
private SkuClient skuClient;
public void creatClient() {
// 创建索引
this.elasticsearchTemplate.createIndex(SearchSku.class);
// 配置映射
this.elasticsearchTemplate.putMapping(SearchSku.class);
ResponseEntity<List<SearchSku>> resp = skuClient.findESData();
List<SearchSku> list = resp.getBody();
skuRepository.saveAll(list);
}
public void initeData() {
ResponseEntity<List<SearchSku>> resp = skuClient.findESData();
List<SearchSku> list = resp.getBody();
skuRepository.saveAll(list);
}
/**
* 搜索
*
* @param req
* @return
*/
public SearchResult findSkuByCondition(SkuSearchRequest req) {
System.out.println("req:" + req);
//初始化数据
boolean exists = elasticsearchTemplate.indexExists("skus01");
if (!exists) {
creatClient();
}
Page<SearchSku> skuPage = skuRepository.search(new NativeSearchQueryBuilder().build());
if (skuPage.getSize() == 0) {
initeData();
}
//1. 准备自定义查询的对象
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//2. 多条件搜索依赖BoolQuery
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//3. 条件一:验证es中的cat3id和页面传过来的catid相等
// es中如何比较Integer类型相等
boolQueryBuilder.must(QueryBuilders.termQuery("cat3_id", req.getCatid()));
// 4. 条件二:验证brand_id
if (req.getBrand_id() != null && !"".equals(req.getBrand_id())) {
boolQueryBuilder.must(QueryBuilders.termQuery("brand_id", req.getBrand_id()));
}
//5. 条件三:规格搜索
//5.1 将规格转成Map集合
HashMap<String, String> map = null;
// 判断spec_list是否有值
if (!"".equals(req.getSpec_list())) {
map = new HashMap<>();
//1. 分割字符 机身颜色=金色 内存=4GB 机身颜色=
String[] spec_list_array = req.getSpec_list().split(",");
//2. 遍历数组
for (String s : spec_list_array) {
//3. 根据等号切割字符串
String[] values = s.split("=");
//4. values[0] 机身颜色 内存
// values[1] 金色 4GB
if (values.length == 1) {
//5. 当机身颜色没有对应的数据的时候,表明页面选择的是“不限”,此处就可以删除
map.remove(values[0]);
} else {
map.put(values[0], values[1]);
}
}
}
//5.2 添加过滤规格的条件
if (map != null) {
// 遍历Map集合
Set<String> keys = map.keySet();
for (String key : keys) {
String value = map.get(key);
/**
* 拿着key和value去es中匹配
* es中的列:
* specs.机身颜色
* specs.内存
* specs.机身存储
* 所以我们需拼接
* specs: 是es中的map对象的名字
* key: map集合中的key
* .keyword:固定搭配
**/
key = "specs." + key + ".keyword";
// 添加条件
boolQueryBuilder.must(QueryBuilders.termQuery(key, value));
}
}
// 6. 价格
if (req.getMin_price() != null) {
boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(req.getMin_price()));
}
if (req.getMax_price() != null) {
boolQueryBuilder.must(QueryBuilders.rangeQuery("price").lte(req.getMax_price()));
}
// 7 排序
// 7销量
if ("xl".equals(req.getSort_by())) {
queryBuilder.withSort(SortBuilders.fieldSort("seller_count").order(SortOrder.DESC)
);
}
// 评论
else if ("pl".equals(req.getSort_by())) {
queryBuilder.withSort(SortBuilders.fieldSort("comment_count").order(SortOrder.DESC
));
}
// 上架时间
else if ("sj".equals(req.getSort_by())) {
queryBuilder.withSort(SortBuilders.fieldSort("on_sale_time").order(SortOrder.DESC)
);
}
// 价格
else if ("jg".equals(req.getSort_by()) && "desc".equals(req.getSort_way())) {
queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
} else if ("jg".equals(req.getSort_by()) && "asc".equals(req.getSort_way())) {
queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
}
// 8. 分页
int pageNo = req.getPage() - 1;//为什么要减1,因为elasticsearch的分页从0开始
int size = req.getPer_page();
queryBuilder.withPageable(PageRequest.of(pageNo, size));
//9. queryBuilder关联boolQueryBuilder
queryBuilder.withQuery(boolQueryBuilder);
//10. 执行查询
Page<SearchSku> page = skuRepository.search(queryBuilder.build());
for (SearchSku searchSku : page) {
System.out.println("page:" + searchSku);
}
//11. 获取总数量
long count = page.getTotalElements();
//12. 获取catid
Integer catid = req.getCatid();
//13. 准备data
//13.1 准备List<ReturnSku>
ArrayList<ReturnSku> list = new ArrayList<>();
for (SearchSku s : page) {
// 准备ReturnSku需要的数据
ReturnSku sku = new ReturnSku();
sku.setId(s.getId());
sku.setGoods_name(s.getSku_name());
sku.setPrice(s.getPrice());
sku.setMidlogo(s.getLogo());
sku.setComment_count(s.getComment_count());
// 装进集合
list.add(sku);
}
//14. 准备SearchResult
SearchResult sr = new SearchResult(0, "成功", list, (int) count, catid);
return sr;
}
}
import com.czxy.service.SkuSearchService;
import com.czxy.vo.BaseResult;
import com.czxy.vo.SearchResult;
import com.czxy.vo.SkuSearchRequest;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping
public class SkuSearchController {
@Autowired
private SkuSearchService skuSearchService;
@GetMapping("/goods")
public ResponseEntity<Object> findSkus(SkuSearchRequest req){
SearchResult search = skuSearchService.findSkuByCondition(req);
Map<String, Object> map = new HashedMap();
map.put("data", search);
return ResponseEntity.ok(map);
}
}
elasticSearch 其他用法
import com.czxy.YoupingouWebSearchApplication;
import com.czxy.client.SkuClient;
import com.czxy.dao.SkuRepository;
import com.czxy.vo.SearchSku;
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.Page;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = YoupingouWebSearchApplication.class)
public class SkuClientTest {
@Autowired
private SkuClient skuClient;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Autowired
private SkuRepository skuRepository;
// 获取web-service数据
@Test
public void findAllSkus() throws Exception {
ResponseEntity<List<SearchSku>> resp = skuClient.findESData();
List<SearchSku> list = resp.getBody();
for(SearchSku ss:list){
System.out.println(ss);
}
}
// **************************************** elasticSearch 使用 ************************************************************************
// 创建索引
@Test
public void createIndex(){
// 创建索引
this.elasticsearchTemplate.createIndex(SearchSku.class);
// 配置映射(创建索引类型)
this.elasticsearchTemplate.putMapping(SearchSku.class);
}
//删除索引
@Test
public void deleteIndex(){
this.elasticsearchTemplate.deleteIndex(SearchSku.class);
}
//导入数据
@Test
public void loadData() throws Exception {
ResponseEntity<List<SearchSku>> resp = skuClient.findESData();
List<SearchSku> list = resp.getBody();
for(SearchSku ss:list){
ss.setAll(ss.toString());
System.out.println(ss);
}
this.skuRepository.saveAll(list);
}
//查询索引是否存在
@Test
public void findIndex() {
// IndicesExistsResponse response = elasticsearchTemplate.getClient().admin().indices()
// .exists(new IndicesExistsRequest().indices(new String[]{"skus01"})).actionGet();
// boolean exists = response.isExists();
boolean exists = elasticsearchTemplate.indexExists("skus01");
System.out.println(exists);
}
//查询索引数据
@Test
public void findDatas(){
Page<SearchSku> page = skuRepository.search(new NativeSearchQueryBuilder().build());
System.out.println("page:" + page.getSize());
for (SearchSku searchSku : page) {
System.out.println("page:" + searchSku);
}
}
}
另外还有其他查询用法:ElasticSearch之JavaAPI查询索引(9种)_fengge18306的博客-优快云博客_java查询es索引