<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
配置:
elasticsearch_setting.json
{
"index": {
"number_of_shards": "5",
"max_result_window": "200000000",
"max_ngram_diff": 20,
"analysis": {
"analyzer": {
"ik_pinyin_analyzer": {
"type": "custom",
"max_token_length": "1",
"tokenizer": "ik_smart",
"filter": "pinyin_filter"
},
"pinyin_analyzer": {
"tokenizer": "pinyin_tokenizer"
},
"my_analyzer": {
"type": "custom",
"tokenizer": "my_tokenizer",
"filter": ["lowercase"]
}
},
"tokenizer": {
"my_tokenizer": {
"type": "ngram",
"min_gram": 1,
"max_gram": 1,
"token_chars": [
"letter",
"digit"
]
},
"standard_tokenizer": {
"type": "standard",
"max_token_length": "1"
},
"pinyin_tokenizer": {
"ignore_pinyin_offset": "true",
"keep_joined_full_pinyin": "true",
"keep_none_chinese_in_first_letter": "true",
"lowercase": "true",
"keep_none_chinese_together": "true",
"remove_duplicated_term": "true",
"keep_first_letter": "true",
"keep_separate_first_letter": "true",
"trim_whitespace": "true",
"type": "pinyin",
"keep_none_chinese": "true",
"keep_full_pinyin": "true"
}
},
"filter": {
"pinyin_filter": {
"type": "pinyin",
"keep_first_letter":true,
"keep_separate_first_letter": false,
"keep_full_pinyin": true,
"keep_original": false,
"limit_first_letter_length": 10,
"lowercase": true,
"remove_duplicated_term": true,
"ignore_pinyin_offset": "true",
"keep_joined_full_pinyin": "true",
"keep_none_chinese_in_first_letter": "true",
"keep_none_chinese_together": "true",
"trim_whitespace": "true",
"keep_none_chinese": "true"
}
}
}
}
}
elasticsearch_mapping.json
{
"properties": {
"proName": {
"type": "text",
"analyzer": "my_analyzer",
"search_analyzer": "my_analyzer",
"fields": {
"keyword": {
"type": "keyword"
},
"pinyin": {
"type": "text",
"analyzer": "pinyin_analyzer"
}
}
},
"barCodes": {
"type": "text",
"analyzer": "my_analyzer",
"search_analyzer": "my_analyzer",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"group": {
"type": "nested"
}
}
}
实体类
@Data
@Mapping(mappingPath = "elasticsearch_mapping.json")//设置mapping
@Setting(settingPath = "elasticsearch_setting.json")//设置setting
@Document(indexName = "#{@proTableName}")
public class EsProduct implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
/**
* 店铺id
*/
@Field(name = "shopId", type = FieldType.Long)
private Long shopId;
/**
* 条形码集 用逗号隔开
* Field 复杂分词功能用json配置
*/
private String barCodes;
/**
* 总销量
*/
@Field(name = "proSaleTotal", type = FieldType.Integer)
private Integer proSaleTotal;
/**
* 商家编码
*/
@Field(name = "proCode", type = FieldType.Text)
private String proCode;
/**
* 条形码
*/
@Field(name = "barCode", type = FieldType.Text)
private String barCode;
/**
* 商品名称
* Field 复杂分词功能用json配置
*/
private String proName;
/**
* 商品描述
*/
@Field(name = "proDescribe", type = FieldType.Text)
private String proDescribe;
/**
* 卖家id
*/
@Field(name = "userId", type = FieldType.Long)
private Long userId;
/**
* 创建时间
*/
@Field(type = FieldType.Date, format = DateFormat.date_optional_time)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT+8")
private Date createTime;
/**
* 修改时间
*/
@Field(type = FieldType.Date, format = DateFormat.date_optional_time)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT+8")
private Date editTime;
@Field(name = "isDelete", type = FieldType.Integer)
private Integer isDelete;
@Field(name = "proLabel", type = FieldType.Text)
private String proLabel;
@Field(name = "proLabel", type = FieldType.Double)
private BigDecimal proWeight;
@Field(type = FieldType.Nested)
private List<EsProGroup> group;
}
Daon层
@Repository public interface EsProductDAO extends ElasticsearchRepository<EsProduct, Long> { List<EsProduct> findByProNameLike(String proName); List<EsProduct> findByShopIdOrderByCreateTimeDesc(Long shopId); List<EsProduct> findByShopId(Long shopId, Pageable pageable); List<EsProduct> findByIdIn(List<Long> proIds); }
Serviice层
private final EsProductDAO esProductDAO; esProductDAO.save(product); Page<EsProduct> search(NativeSearchQuery searchQuery); Page<EsProduct> page = esProductService.search(this.paramsConvert(proSearBasicBO).build());
public NativeSearchQueryBuilder paramsConvert(BeEsProSearchBO.ProSearchEsBO proSearBasicBO) {
log.info("ES搜索条件参数:{}", JSON.toJSONString(proSearBasicBO));
// 复合查询
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
if (CommonUtil.isNotEmpty(proSearBasicBO.getBusId())) {
boolQuery.filter(QueryBuilders.termQuery("userId", proSearBasicBO.getBusId()));
}
if (CommonUtil.isNotEmpty(proSearBasicBO.getShowSoldOut()) && (proSearBasicBO.getShowSoldOut() == -1 || proSearBasicBO.getShowSoldOut() == 0)) {
RangeQueryBuilder stockTotal = QueryBuilders.rangeQuery("proStockTotal").gt(0);
TermQueryBuilder isJxcMinusStock = QueryBuilders.termQuery("isJxcMinusStock", 1);
BoolQueryBuilder stockTotalQuery = QueryBuilders.boolQuery().must(stockTotal).should(isJxcMinusStock);
boolQuery.filter(stockTotalQuery);
}
if (CommonUtil.isNotEmpty(proSearBasicBO.getBarCode())) {
boolQuery.must(QueryBuilders.queryStringQuery(proSearBasicBO.getBarCode()).field("barCodes"));
}
if (CommonUtil.isNotEmpty(proSearBasicBO.getGroupId()) && proSearBasicBO.getGroupId() > 0) {
boolQuery.must(QueryBuilders.nestedQuery(EsTableNameConstant.GROUP, QueryBuilders.termQuery(EsTableNameConstant.GROUP + ".groupId", proSearBasicBO.getGroupId()), ScoreMode.None));
}
if (proSearBasicBO.getGroupIds() != null && proSearBasicBO.getGroupIds().size() > 0) {
boolQuery.must(QueryBuilders.nestedQuery(EsTableNameConstant.GROUP, QueryBuilders.termsQuery(EsTableNameConstant.GROUP + ".groupId", proSearBasicBO.getGroupIds()), ScoreMode.None));
}
if (CommonUtil.isNotEmpty(proSearBasicBO.getSearch())) {
String query = CommonUtil.escape(proSearBasicBO.getSearch());
if (proSearBasicBO.getSearchKey().equals(2)) {
QueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("barCodes", query).slop(0).boost(70);
MatchQueryBuilder barCodeBuilder = QueryBuilders.matchQuery("barCodes", query).boost(1);
BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery().should(barCodeBuilder).should(matchPhraseQueryBuilder);
boolQuery.must(shouldQuery);
} else if (proSearBasicBO.getSearchKey().equals(1)) {
QueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("proName", query).slop(0).boost(70);
MatchQueryBuilder proNameBuilder = QueryBuilders.matchQuery("proName", query).boost(1);
BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery().should(matchPhraseQueryBuilder).should(proNameBuilder);
boolQuery.must(shouldQuery);
} else {
QueryBuilder matchPhraseBuilder = QueryBuilders.matchPhraseQuery("proName", query).slop(0).boost(2);
MatchQueryBuilder proNameBuilder = QueryBuilders.matchQuery("proName", query).boost(1);
QueryBuilder barPhraseBuilder = QueryBuilders.matchPhraseQuery("barCodes", query).slop(0).boost(500);
MatchQueryBuilder barCodeBuilder = QueryBuilders.matchQuery("barCodes", query).boost(50);
BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery().should(matchPhraseBuilder).should(proNameBuilder).should(barCodeBuilder);
boolQuery.must(shouldQuery);
}
}
queryBuilder.withQuery(boolQuery);
if (proSearBasicBO.getSortStyle() == null) {
proSearBasicBO.setSortStyle(0);
}
//排序
if (CommonUtil.isNotEmpty(proSearBasicBO.getSortStyle())) {
if (proSearBasicBO.getSortStyle() == ProSortConstant.ID_DOWN) {
if (proSearBasicBO.getActStyle() == 13) {
queryBuilder.withSort(new FieldSortBuilder(EsTableNameConstant.JXC_PRICE + ".createTime").order(SortOrder.DESC).setNestedPath(EsTableNameConstant.JXC_PRICE));
queryBuilder.withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC));
} else {
queryBuilder.withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
}
} else if (proSearBasicBO.getSortStyle() == ProSortConstant.SALE_DOWN) {
queryBuilder.withSort(SortBuilders.fieldSort("proSaleTotal").order(SortOrder.DESC));
if (proSearBasicBO.getActStyle() == 13) {
queryBuilder.withSort(new FieldSortBuilder(EsTableNameConstant.JXC_PRICE + ".createTime").order(SortOrder.DESC).setNestedPath(EsTableNameConstant.JXC_PRICE));
} else {
queryBuilder.withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
}
}
}
// 分页
if (CommonUtil.isNotEmpty(proSearBasicBO.getCurPage())) {
if (proSearBasicBO.getCurPage() > 0) {
proSearBasicBO.setCurPage(proSearBasicBO.getCurPage() - 1);
}
queryBuilder.withPageable(PageRequest.of(proSearBasicBO.getCurPage(), proSearBasicBO.getPageSize()));
}
log.info("ES搜索条件转成ES条件参数:{}", JSON.toJSONString(boolQuery.toString()));
return queryBuilder;
}