1.使用javaApi接口创建searchrequest:
/**
* 构建检索请求:
* #模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存),排序,分页,高亮,聚合分析
* */
private SearchRequest buildSearchRequest(SearchParam searchParam) {
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();//构建DSL语句
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
/**
* 模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存)
* */
//1.构建bool-query
//1.1 模糊匹配 bool - must
if (!StringUtils.isEmpty(searchParam.getKeyWord())){
boolQueryBuilder.must(QueryBuilders.matchQuery("skuTitle",searchParam.getKeyWord()));
}
//1.2 bool - filter 按照三级分类id查询
if (searchParam.getCatalog3Id()!=null){
boolQueryBuilder.filter(QueryBuilders.termQuery("catalogId",searchParam.getCatalog3Id()));
}
//1.3 bool -filter 按照品牌id查询
if (searchParam.getBrandId()!=null&&searchParam.getBrandId().size()>0){
boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId",searchParam.getBrandId()));
}
//1.4 bool -filter - nested 按照指定的属性查询
if (searchParam.getAttrs()!=null&&searchParam.getAttrs().size()>0){
//每一个属性查询必须都得生成一个nested查询
for (String attr : searchParam.getAttrs()) {
BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
//attrs=1_5寸:8寸&attrs=2_16G:8G
String[] attrSplit = attr.split("_");
String attrId = attrSplit[0];
String[] attrValues = attrSplit[1].split(":");
nestedBoolQuery.must(QueryBuilders.termQuery("attrs.attrId",attrId));
nestedBoolQuery.must(QueryBuilders.termsQuery("attrs.attrValue",attrValues));
//每一个必须都得生成一个nested查询
NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", nestedBoolQuery, ScoreMode.None);
boolQueryBuilder.filter(nestedQuery);
}
}
//1.5 bool -filter 是否有库存查询
if (searchParam.getHasStock()==null){
//如果没有传输是否有库存这个参数,默认查找有库存的
boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",true));
}else {
boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",searchParam.getHasStock()==1));
}
//1.6按照价格区间
if (!StringUtils.isEmpty(searchParam.getSkuPrice())){
RangeQueryBuilder skuPriceRangeQuery = QueryBuilders.rangeQuery("skuPrice");
String[] s = searchParam.getSkuPrice().split("_");
if (s.length == 2 ){
//区间
skuPriceRangeQuery.gte(s[0]).lte(s[1]);
}else if (s.length==1){
if (searchParam.getSkuPrice().startsWith("_")){
skuPriceRangeQuery.lte(s[0]);
}
if (searchParam.getSkuPrice().endsWith("_")){
skuPriceRangeQuery.gte(s[0]);
}
}
boolQueryBuilder.filter(skuPriceRangeQuery);
}
searchSourceBuilder.query(boolQueryBuilder);
/**
* 排序,分页,
* sort=saleCount_asc/desc
* sort=skuPrice_asc/desc
* sort= hotScore_asc/desc
* */
if (!StringUtils.isEmpty(searchParam.getSort())){
String sort = searchParam.getSort();
String[] sortSplit = sort.split("_");
SortOrder sortOrder = sortSplit[1].equalsIgnoreCase("asc")?SortOrder.ASC:SortOrder.DESC;
searchSourceBuilder.sort(sortSplit[0],sortOrder);
}
//分页
if (searchParam.getPageNum()==null){
//如果没有传输pagenum参数,默认为第一页
searchSourceBuilder.from(((1-1)*EsConstant.PRODUCT_PAGESIZE));
searchSourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
}else {
searchSourceBuilder.from((searchParam.getPageNum()-1)*EsConstant.PRODUCT_PAGESIZE);
searchSourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
}
/**
* 高亮
* */
if (!StringUtils.isEmpty(searchParam.getKeyWord())){
HighlightBuilder highlightBuilder=new HighlightBuilder();
highlightBuilder.field("skuTitle");
highlightBuilder.preTags("<b style= 'color:red'>");
highlightBuilder.postTags("</b>");
searchSourceBuilder.highlighter(highlightBuilder);
}
/**
* 聚合分析
* */
//1.品牌的聚合
TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");
brand_agg.field("brandId");
//品牌的子聚合
brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));
brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));
//TODO 1. 品牌的聚合
searchSourceBuilder.aggregation(brand_agg);
//2.分类聚合 catalog_agg
TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);
catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));
//TODO 2. 分类的聚合
searchSourceBuilder.aggregation(catalog_agg);
//3.属性聚合 attr_agg
NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs");
//3.1聚合当前所有的attrId
TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId").size(10);
//3.2聚合分析出当前attr_id对应的名字
attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));
//3.3聚合分析出当前attr_id对应的所有可能的属性值attrValue
attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50));
attr_agg.subAggregation(attr_id_agg);
//TODO 3. 属性的聚合
searchSourceBuilder.aggregation(attr_agg);
//打印构造的DSL
String s = searchSourceBuilder.toString();
System.out.println("构建的DSL:"+s);
SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, searchSourceBuilder);
return searchRequest;
}
2.传递过来的参数:
http://localhost:12000/list.html?keyWord=HUAWEI&catalog3Id=225&attrs=11_第一代骁龙8&skuPrice=4000_
3.使用postman发送形成的DSL语句:
GET product/_search
{
"from": 0,
"size": 5,
"query": {
"bool": {
"must": [
{
"match": {
"skuTitle": {
"query": "HUAWEI",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1.0
}
}
}
],
"filter": [
{
"term": {
"catalogId": {
"value": 225,
"boost": 1.0
}
}
},
{
"nested": {
"query": {
"bool": {
"must": [
{
"term": {
"attrs.attrId": {
"value": "11",
"boost": 1.0
}
}
},
{
"terms": {
"attrs.attrValue": [
"第一代骁龙8"
],
"boost": 1.0
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
},
"path": "attrs",
"ignore_unmapped": false,
"score_mode": "none",
"boost": 1.0
}
},
{
"term": {
"hasStock": {
"value": true,
"boost": 1.0
}
}
},
{
"range": {
"skuPrice": {
"from": "4000",
"to": null,
"include_lower": true,
"include_upper": true,
"boost": 1.0
}
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
},
"aggregations": {
"brand_agg": {
"terms": {
"field": "brandId",
"size": 10,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
},
"aggregations": {
"brand_name_agg": {
"terms": {
"field": "brandName",
"size": 1,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
}
},
"brand_img_agg": {
"terms": {
"field": "brandImg",
"size": 1,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
}
}
}
},
"catalog_agg": {
"terms": {
"field": "catalogId",
"size": 20,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
},
"aggregations": {
"catalog_name_agg": {
"terms": {
"field": "catalogName",
"size": 1,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
}
}
}
},
"attr_agg": {
"nested": {
"path": "attrs"
},
"aggregations": {
"attr_id_agg": {
"terms": {
"field": "attrs.attrId",
"size": 10,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
},
"aggregations": {
"attr_name_agg": {
"terms": {
"field": "attrs.attrName",
"size": 1,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
}
},
"attr_value_agg": {
"terms": {
"field": "attrs.attrValue",
"size": 50,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
}
}
}
}
}
}
},
"highlight": {
"pre_tags": [
"<b style= 'color:red'>"
],
"post_tags": [
"</b>"
],
"fields": {
"skuTitle": {}
}
}
}
4.查询到的结果:
{ "took" : 5, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 0.66301036, "hits" : [ { "_index" : "product", "_type" : "_doc", "_id" : "7", "_score" : 0.66301036, "_source" : { "attrs" : [ { "attrId" : 11, "attrName" : "CPU型号", "attrValue" : "第一代骁龙8" } ], "brandId" : 4, "brandImg" : "https://gulimall-nan1.oss-cn-beijing.aliyuncs.com/2022-11-30/90b15473-072f-42d4-8c35-11a6cd1161ac_huawei.png", "brandName" : "华为", "catalogId" : 225, "catalogName" : "手机", "hasStock" : true, "hotScore" : 0, "saleCount" : 0, "skuId" : 7, "skuImg" : "https://gulimall-nan1.oss-cn-beijing.aliyuncs.com/2022-12-05//ff79ccd7-f380-4805-86aa-17624e2f59e3_d511faab82abb34b.jpg", "skuPrice" : 4999.0, "skuTitle" : "HUAWEI Mate 50 冰霜银 8+128GB直屏旗舰 超光变XMAGE影像 北斗卫星消息 低电量应急模式", "spuId" : 15 }, "highlight" : { "skuTitle" : [ "<b style= 'color:red'>HUAWEI</b> Mate 50 冰霜银 8+128GB直屏旗舰 超光变XMAGE影像 北斗卫星消息 低电量应急模式" ] } } ] }, "aggregations" : { "catalog_agg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : 225, "doc_count" : 1, "catalog_name_agg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "手机", "doc_count" : 1 } ] } } ] }, "attr_agg" : { "doc_count" : 1, "attr_id_agg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : 11, "doc_count" : 1, "attr_name_agg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "CPU型号", "doc_count" : 1 } ] }, "attr_value_agg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "第一代骁龙8", "doc_count" : 1 } ] } } ] } }, "brand_agg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : 4, "doc_count" : 1, "brand_img_agg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "https://gulimall-nan1.oss-cn-beijing.aliyuncs.com/2022-11-30/90b15473-072f-42d4-8c35-11a6cd1161ac_huawei.png", "doc_count" : 1 } ] }, "brand_name_agg" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "华为", "doc_count" : 1 } ] } } ] } } }