1、pom中引入依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.14.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.14.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.14.0</version>
</dependency>
<dependency>
<groupId>cn.easy-es</groupId>
<artifactId>easy-es-boot-starter</artifactId>
<version>2.0.0-beta1</version>
</dependency>
2、yml文件增加配置
easy-es:
address: 192.168.3.133:9210
enable: true
db-config:
map-underscore-to-camel-case: true
id-type: customize
refresh-policy: immediate
enable-track-total-hits: true
3、实体索引
package com.cn.es.entity;
import cn.easyes.annotation.HighLight;
import cn.easyes.annotation.IndexField;
import cn.easyes.annotation.IndexId;
import cn.easyes.annotation.IndexName;
import cn.easyes.annotation.rely.Analyzer;
import cn.easyes.annotation.rely.FieldType;
import cn.easyes.annotation.rely.IdType;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* description: ProductEntity <br>
* date: 23.2.27 15:12 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Setter
@Getter
@IndexName(value = "product_entity", shardsNum = 1, replicasNum = 1, aliasName = "Product")
//@Document(indexName = "product-index1", createIndex = true, type = "_doc")
public class ProductEntity {
//id是业务中添加的,不是es自动生成的
@IndexId(type = IdType.CUSTOMIZE)
private Long id;
@HighLight(mappingField = "resume", fragmentSize = 10)//将查询到的高亮内容放到resume字段中
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_MAX_WORD, searchAnalyzer = Analyzer.IK_SMART)
private String name;
//拼音分词
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.PINYIN, searchAnalyzer = Analyzer.PINYIN)
private String name1;
//存放高亮
@IndexField(exist = false)
private String resume;
@IndexField(fieldType = FieldType.KEYWORD)
@ApiModelProperty(value = "销量")
private Integer saleNum;
@IndexField(fieldType = FieldType.KEYWORD)
@ApiModelProperty(value = "价格")
private Double price;
/**
* 品牌ID
*/
@IndexField(fieldType = FieldType.LONG)
private Long brandId;
/**
* 分类ID
*/
@IndexField(fieldType = FieldType.LONG)
private Long categoryId;
/**
* 店铺id
*/
@IndexField(fieldType = FieldType.LONG)
private Long shopId;
@IndexField(fieldType = FieldType.KEYWORD)
private Long addTime;
}
4、mapper
import cn.easyes.core.core.BaseEsMapper;
import com.cn.es.entity.ProductEntity;
public interface IProduc2Mapper extends BaseEsMapper<ProductEntity> {
}
5、service
package com.cn.es.service;
import cn.easyes.core.biz.EsPageInfo;
import cn.easyes.core.biz.SAPageInfo;
import cn.easyes.core.conditions.select.LambdaEsQueryWrapper;
import com.cn.es.entity.ProductEntity;
import com.cn.es.mapper.IProduc2Mapper;
import com.cn.es.vo.ProductSearch;
import com.cn.exception.MyException;
import com.cn.page.PageVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* description: Product2Service <br>
* date: 23.3.20 14:29 <br>
* author: cn_yaojin <br>
* version: 1.0 <br>
*/
@Service
@Slf4j
public class Product2Service {
@Autowired
private IProduc2Mapper produc2Mapper;
private String indexName = "product_entity";
public void create() {
boolean exist = this.produc2Mapper.existsIndex(indexName);
if (!exist) {
this.produc2Mapper.createIndex(indexName);
} else {
throw new MyException("索引已存在");
}
}
public void drop() {
boolean result = this.produc2Mapper.deleteIndex(indexName);
System.out.println(result);
}
public void save(ProductEntity info) {
info.setName1(info.getName()); //将商品名称放到name1拼音字段中
info.setAddTime(System.currentTimeMillis());
var data = this.produc2Mapper.selectById(info.getId());
if (data != null) {
update(info);
} else {
this.produc2Mapper.insert(info);
}
}
public void update(ProductEntity info) {
this.produc2Mapper.updateById(info);
}
public EsPageInfo<ProductEntity> page(PageVo<ProductSearch> pageVo) {
ProductSearch search = pageVo.getParam();
LambdaEsQueryWrapper<ProductEntity> queryWrapper = new LambdaEsQueryWrapper<>();
if (StringUtils.isNotEmpty(search.getName())) {
// queryWrapper.like("name", search.getName());
// queryWrapper.matchPhrase(ProductEntity::getName, search.getName());
queryWrapper.matchPhrase(ProductEntity::getName1, search.getName())
.or().matchPhrase(ProductEntity::getName, search.getName());
// queryWrapper.multiMatchQuery("name", search.getName());
}
if (search.getPrice1() > -1) {
queryWrapper.ge("price", search.getPrice1());
}
if (search.getPrice2() > -1) {
queryWrapper.le("price", search.getPrice2());
}
if (search.getSortPrice()) {
queryWrapper.orderByDesc("price");
}
if (search.getSortSaleNum()) {
queryWrapper.orderByDesc("saleNum");
}
EsPageInfo<ProductEntity> page = this.produc2Mapper.pageQuery(queryWrapper, pageVo.getPageNum(), pageVo.getPageSize());
return page;
}
public Object searchAfter(ProductSearch search) {
LambdaEsQueryWrapper<ProductEntity> queryWrapper = new LambdaEsQueryWrapper<>();
if (StringUtils.isNotEmpty(search.getName())) {
queryWrapper.matchPhrase(ProductEntity::getName1, search.getName())
.or().matchPhrase(ProductEntity::getName, search.getName());
}
if (search.getPrice1() > -1) {
queryWrapper.ge("price", search.getPrice1());
}
if (search.getPrice2() > -1) {
queryWrapper.le("price", search.getPrice2());
}
queryWrapper.orderByDesc("id"); //以id为排序方式
SAPageInfo<ProductEntity> saPageInfo = produc2Mapper.searchAfterPage(queryWrapper, search.getNextSearchAfter(), search.getSize());
return saPageInfo;
}
public void del(String id) {
this.produc2Mapper.deleteById(id);
}
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
}
}
6、controller
package com.cn.es.controller;
import cn.easyes.core.biz.EsPageInfo;
import cn.easyes.core.biz.SAPageInfo;
import com.cn.es.entity.ProductEntity;
import com.cn.es.service.Product2Service;
import com.cn.es.vo.ProductSearch;
import com.cn.msg.ResultMsg;
import com.cn.page.PageVo;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "admin/product")
@Api(tags = "产品")
@Slf4j
public class ProductController {
@Autowired
private Product2Service product2Service;
@ApiOperation(value = "新建索引")
@GetMapping(value = "crate")
public ResultMsg create() {
this.product2Service.create();
return ResultMsg.builder();
}
@ApiOperation(value = "删除索引")
@GetMapping(value = "drop")
public ResultMsg drop() {
this.product2Service.drop();
return ResultMsg.builder();
}
@ApiOperation(value = "保存")
@PostMapping(value = "save")
public ResultMsg save(
@RequestBody ProductEntity info
) {
this.product2Service.save(info);
return ResultMsg.builder();
}
@ApiOperation(value = "easy-es 浅分页")
@PostMapping(value = "page")
public ResultMsg<EsPageInfo<ProductEntity>> page1(
@RequestBody PageVo<ProductSearch> search
) {
return ResultMsg.builder().setData(this.product2Service.page(search));
}
@ApiOperation(value = "easy-es searchAfter查询分页")
@PostMapping(value = "page2")
public ResultMsg<SAPageInfo<ProductEntity>> page2(
@RequestBody ProductSearch search
) {
return ResultMsg.builder().setData(this.product2Service.searchAfter(search));
}
@ApiOperation(value = "删除")
@GetMapping(value = "del")
public ResultMsg del(
@RequestParam String id
) {
this.product2Service.del(id);
return ResultMsg.builder();
}
}
7、新增或修改数据
{
"brandId": 0,
"categoryId": 1,
"id": 8,
"multiField": "",
"name": "烤肉、啤酒",
"price": 130,
"saleNum": 124,
"shopId": 1
}
8、浅分页
{
"pageNum": 1,
"pageSize": 20,
"param": {
"name": "",//支持拼音搜索:niurou
"price1": -1,
"price2": -1,
"sortPrice": true,
"sortSaleNum": true
}
}
9、searchAfter 分页,必须有一个唯一的排序属性,例如:id
{
"name": "牛肉面",
"size": 2 //查询2条
}
下一页:
{
"name": "",
"size": 2,
"nextSearchAfter": [
"7"
]
}
当使用 searchAfter分页时,想使用销量、价格 等排序来展示数据,需要结合一个唯一且连续的属性来组合排序,否则容易导致数据丢失。比如当牛肉面二细销量为10、牛肉三细销量也为10的时候,如果仅使用销量作为排序字段,那么以上两条数据只能查到一条。但是如果在销量排序的基础上,再新增一个唯一且连续的属性来排序(该唯一且连续的属性必须放在所有排序字段的最后面),那么可以避免数据丢失的问题。示例代码如下:
if (search.getSortSaleNum()) {
queryWrapper.orderByDesc("saleNum"); //销量排序
queryWrapper.orderByDesc("_doc"); //doc是es自动生成的,唯一且连续,也可以使用id代替_doc
//以上两者组合使用,在销量排序的基础上,防止相同销量数据的丢失,而且_doc排序必须放在最后面
}
11、高亮查询,高亮属性已经在实体:ProductEntity 中的name属性上设置了,所以此处使用name字段正常查询即可。文章来源:https://www.toymoban.com/news/detail-667190.html
{
"pageNum": 1,
"pageSize": 20,
"param": {
"name": "牛肉面"
}
}
{
"msg": "成功",
"data": {
"total": 6,
"list": [
{
"id": 5,
"name": "牛肉面宽",
"name1": "牛肉面宽",
"resume": "<em>牛肉面</em>宽",
"saleNum": 20,
"price": 7,
"brandId": 0,
"categoryId": 1,
"shopId": 1,
"addTime": null
},
{
"id": 1,
"name": "牛肉面细",
"name1": "牛肉面细",
"resume": "<em>牛肉面</em>细",
"saleNum": 7,
"price": 7,
"brandId": 0,
"categoryId": 1,
"shopId": 1,
"addTime": null
},
{
"id": 2,
"name": "牛肉面毛细",
"name1": "牛肉面毛细",
"resume": "<em>牛肉面</em>毛细",
"saleNum": 8,
"price": 6,
"brandId": 0,
"categoryId": 1,
"shopId": 1,
"addTime": null
},
{
"id": 3,
"name": "牛肉面三细",
"name1": "牛肉面三细",
"resume": "<em>牛肉面</em>三细",
"saleNum": 10,
"price": 6.5,
"brandId": 0,
"categoryId": 1,
"shopId": 1,
"addTime": null
},
{
"id": 4,
"name": "牛肉面二细",
"name1": "牛肉面二细",
"resume": "<em>牛肉面</em>二细",
"saleNum": 31,
"price": 7.5,
"brandId": 0,
"categoryId": 1,
"shopId": 1,
"addTime": null
},
{
"id": 6,
"name": "牛肉面大宽",
"name1": "牛肉面大宽",
"resume": "<em>牛肉面</em>大宽",
"saleNum": 10,
"price": 7,
"brandId": 0,
"categoryId": 1,
"shopId": 1,
"addTime": null
}
],
"pageNum": 1,
"pageSize": 20,
"size": 6,
"startRow": 0,
"endRow": 5,
"pages": 1,
"prePage": 0,
"nextPage": 0,
"hasPreviousPage": false,
"hasNextPage": false,
"navigatePages": 8,
"navigatePageNums": [
1
],
"navigateFirstPage": 1,
"navigateLastPage": 1,
"firstPage": true,
"lastPage": true
},
"success": true,
"code": 200
}
文章来源地址https://www.toymoban.com/news/detail-667190.html
到了这里,关于easy-es 使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!