1,目标
实现es分词查询与模糊查询
2.关于分词文章参考以下连接
https://www.cnblogs.com/zlslch/p/6440373.html
3.索引字段定义
商品名称定义了中文分词器,因为名称为中文组成可以进行分词查询
商品编码定义精确查询
"product_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
},
"maxword": {
"analyzer": "ik_max_word",
"type": "text"
},
"smart": {
"analyzer": "ik_smart",
"type": "text"
}
}
"product_code": {
"type": "keyword"
},
4.实现
1)商品编码,名称模糊查询
if (org.apache.commons.lang3.StringUtils.isNotBlank(req.getSearchKey())) {
BoolQueryBuilder multiFiledQuery = QueryBuilders.boolQuery();
multiFiledQuery.should(QueryBuilders.termsQuery(convertToUnderScore(ResPurchaseWideInfo::getProductCode), req.getSearchKey()));
multiFiledQuery.should(new WildcardQueryBuilder(convertToUnderScore(ResPurchaseWideInfo::getProductCode), "*".concat(req.getSearchKey()).concat("*")));
multiFiledQuery.should(new WildcardQueryBuilder(convertToUnderScore(ResPurchaseWideInfo::getProductName).concat(".keyword"), "*".concat(req.getSearchKey().concat("*"))));
multiFiledQuery.should(QueryBuilders.termsQuery(convertToUnderScore(ResPurchaseWideInfo::getProductName).concat(".keyword"), req.getSearchKey()));
multiFiledQuery.should(QueryBuilders.termsQuery(convertToUnderScore(ResPurchaseWideInfo::getBarCode), req.getSearchKey()));
multiFiledQuery.minimumShouldMatch(1);
boolQuery.must(multiFiledQuery);
}
2)商品名称分词查询
if (StringUtils.isNumeric(vo.getSearchKey())) {//数字格式
boolQueryBuilder.filter(QueryBuilders.termsQuery(convertToUnderScore(ResPurchaseWideInfo::getPurchaseGroupCode), vo.getPurchaseGroupCodes()))
.should(QueryBuilders.termQuery(convertToUnderScore(ResPurchaseWideInfo::getProductCode), vo.getSearchKey()))
.should(new WildcardQueryBuilder(convertToUnderScore(ResPurchaseWideInfo::getProductCode), "*".concat(vo.getSearchKey()).concat("*")))
.should(QueryBuilders.termQuery(convertToUnderScore(ResPurchaseWideInfo::getBarCode), vo.getSearchKey()))
.should(new WildcardQueryBuilder(convertToUnderScore(ResPurchaseWideInfo::getBarCode), "*".concat(vo.getSearchKey()).concat("*")))
.minimumShouldMatch(1);
} else {//非数字格式
boolQueryBuilder.filter(QueryBuilders.termsQuery(convertToUnderScore(ResPurchaseWideInfo::getPurchaseGroupCode), vo.getPurchaseGroupCodes()))
.must(QueryBuilders.queryStringQuery("product_name:" + vo.getSearchKey()).defaultOperator(QueryStringQueryBuilder.DEFAULT_OPERATOR));
}
5.特别关注
1)名称模糊查询要拼接.keyword
2)es创建索引注意字段类型设计
为什么加.keyword原因参考:
以上为例,为什么模糊查询商品名称不加.keyword查询不到数据
比如商品名称是"我是中国人",查询条件为"中国人",商品名称分词后可能为'我','是','中国',‘人’,,那么*中国人*是查询不到数据的。但是一般字段加了ik_samrt分词器,会进行比较粗粒度分词,我是中国人,会分出 ‘中国人’,一般是可以查询到的。
而加了.keyword就代表不会对商品名称进行分词了,模糊查询*中国人*肯定可以查询到的。