参考京东查询商品界面来实现!
1、导入依赖
<properties>
<!--修改默认版本号,默认为6版本-->
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.1</version>
</dependency>
2、配置连接地址
@Configuration
public class ElasticsearchConfig {
public static final RequestOptions COMMON_OPTIONS;
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// builder.addHeader("Authorization", "Bearer " + TOKEN);
// builder.setHttpAsyncResponseConsumerFactory(
// new HttpAsyncResponseConsumerFactory
// .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
@Bean
public RestHighLevelClient esRestClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("192.168.8.110", 9200, "http")));
return client;
}
}
3、查询
数据结构:
PUT products
{
"mappings": {
"properties": {
"skuId": {
"type": "long"
},
"spuId": {
"type": "keyword"
},
"skuTitle": {
"type": "text",
"analyzer": "ik_smart"
},
"skuPrice": {
"type": "keyword"
},
"skuImg": {
"type": "keyword"
},
"saleCount": {
"type": "long"
},
"hasStock": {
"type": "boolean"
},
"hotScore": {
"type": "long"
},
"brandId": {
"type": "long"
},
"catalogId": {
"type": "long"
},
"brandName": {
"type": "keyword"
},
"brandImg": {
"type": "keyword"
},
"catalogName": {
"type": "keyword"
},
"attrs": {
"type": "nested",
"properties": {
"attrId": {
"type": "long"
},
"attrName": {
"type": "keyword"
},
"attrValue": {
"type": "keyword"
}
}
}
}
}
}
DSL语句:
GET products/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"skuTitle": "华为"
}
}
],
"filter": [
{
"term": {
"catalogId": "225"
}
},
{
"terms": {
"brandId": [
"1",
"2",
"9"
]
}
},
{
"nested": {
"path": "attrs",
"query": {
"bool": {
"must": [
{
"term": {
"attrs.attrId": {
"value": "15"
}
}
},
{
"terms": {
"attrs.attrValue": [
"海思",
"以官网信息为主"
]
}
}
]
}
}
}
},
{
"term": {
"hasStock":{
"value":"true"
}
}
},
{
"range": {
"skuPrice": {
"gte": 0,
"lte": 6000
}
}
}
]
}
},
"sort": [
{
"skuPrice": {
"order": "desc"
}
}
],
"from": 0,
"size": 5,
"highlight": {
"fields": {"skuTitle":{}},
"pre_tags": "<b style='color:red'>",
"post_tags": "</b>"
},
"aggs": {
"brand_agg": {
"terms": {
"field": "brandId",
"size": 10
},
"aggs": {
"brandName_agg": {
"terms": {
"field": "brandName",
"size": 10
}
},
"brand_img_agg":{
"terms": {
"field": "brandImg",
"size": 10
}
}
}
},
"catalog_agg":{
"terms": {
"field": "catalogId",
"size": 10
},
"aggs": {
"calalog_name_agg":{
"terms": {
"field": "catalogName",
"size": 10
}
}
}
},
"attr_agg":{
"nested": {
"path": "attrs"
},
"aggs": {
"attr_id_agg": {
"terms": {
"field": "attrs.attrId",
"size": 10
},
"aggs": {
"attr_name_agg": {
"terms": {
"field": "attrs.attrName",
"size": 10
}
},
"attr_value_agg":{
"terms": {
"field": "attrs.attrValue",
"size": 10
}
}
}
}
}
}
}
}
代码实现:
@Autowired
private RestHighLevelClient client;
/**
* 模糊匹配,过滤,排序,分页,高亮,聚合分析
*/
@Test
public void search2() throws IOException {
// DSL,检索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
/**
* 模糊匹配,过滤 ,下面需要特别注意termQuery 和 termsQuery 的编写
*/
//1、构建bool - query
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// 1.1、must - 模糊匹配
boolQuery.must(QueryBuilders.matchQuery("skuTitle","华为"));
// 1.2、bool - filter 按照分类ID
boolQuery.filter(QueryBuilders.termQuery("catalogId",225));
// 1.2、bool - filter 按照品牌ID
boolQuery.filter(QueryBuilders.termsQuery("brandId",new Long[]{1L,2L,9L}));
// 1.2、bool - filter 按照指定的属性(嵌入式) ScoreMode.None不参与评分
BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
nestedBoolQuery.must(QueryBuilders.termQuery("attrs.attrId",15));
nestedBoolQuery.must(QueryBuilders.termsQuery("attrs.attrValue",new String[]{"海思","以官网信息为主"}));
NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", nestedBoolQuery, ScoreMode.None);
boolQuery.filter(nestedQuery);
BoolQueryBuilder nestedBoolQuery1 = QueryBuilders.boolQuery();
nestedBoolQuery1.must(QueryBuilders.termQuery("attrs.attrId",16));
nestedBoolQuery1.must(QueryBuilders.termsQuery("attrs.attrValue",new String[]{"i5","以官网信息为主"}));
NestedQueryBuilder nestedQuery1 = QueryBuilders.nestedQuery("attrs", nestedBoolQuery, ScoreMode.None);
boolQuery.filter(nestedQuery1);
// 1.2、bool - filter 按照库存是否有
boolQuery.filter(QueryBuilders.termQuery("hasStock",true));
// 1.2、bool - filter 按照价格区间
boolQuery.filter(QueryBuilders.rangeQuery("skuPrice").gte("0").lte("6000"));
//把所有条件封装起来
sourceBuilder.query(boolQuery);
/**
* 排序,分页,高亮
*/
//排序
sourceBuilder.sort("skuPrice", SortOrder.DESC);
//分页
sourceBuilder.from(0);
sourceBuilder.size(5);
//高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("skuTitle");
highlightBuilder.preTags("<b style='color:red'>");
highlightBuilder.postTags("</b>");
sourceBuilder.highlighter(highlightBuilder);
/**
* 聚合分析
*/
//1、品牌聚合
TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");
brand_agg.field("brandId").size(50); //只查询50条
//子聚合
brand_agg.subAggregation(AggregationBuilders.terms("brandName_agg").field("brandName").size(1));
brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));
sourceBuilder.aggregation(brand_agg);
//2、分类聚合
TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg");
catalog_agg.field("catalogId").size(2);
catalog_agg.subAggregation(AggregationBuilders.terms("calalog_name_agg").field("catalogName").size(1));
sourceBuilder.aggregation(catalog_agg);
//3、属性聚合
NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs");
TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId");
attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));
attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(1));
attr_agg.subAggregation(attr_id_agg);
sourceBuilder.aggregation(attr_agg);
System.out.println("构建的DSL语句:"+sourceBuilder.toString());
// 创建检索请求
SearchRequest request = new SearchRequest(new String[]{"products"},sourceBuilder);
// 2、执行检索
SearchResponse response = client.search(request, ElasticsearchConfig.COMMON_OPTIONS);
// 3、分析结果
System.out.println(response.toString());
}