11.ElasticSearch实战3——检索服务-SearchRequest构建-检
索
1. 检索
根据DSL语句构建检索条件
1.1 DSL语句
表格式个人简历GET gulimall_product/_arch
{
"query": {
"bool": {
"must": [
{
"match": {
"skuTitle": "华为"
}
}
],
"filter": [
{
"term": {
"catalogId": "1111133"
}
},
{
"terms": {
"brandId": [
"3",
"5"
]
}
},
{
"term": {
"hasStock": true
}
},
{
"nested": {
"path": "attrs",
"query": {
"bool": {
"must": [
{
"term": {
"attrs.attrId": {
"value": "15"
}
}
},
{
"terms": {
"attrs.attrValue": [
"aaa",
"⽩⾊",
"OCE-AN10"
]
}
}
}
]
}
},
"sort": [
{
"skuPrice": {
"order": "desc"
}
}
],
"aggs": {
"brand_agg": {
"terms": {
"field": "brandId",
"size": 10
},
"aggs": {
"brand_name_agg": {
"terms": {
"field": "brandName",
dream什么意思"size": 10
}
},
"brand_img_agg":{
"terms": {
"field": "brandImg",
"size": 10
}
}
}
},
价值观定义"catalog_agg":{
"terms": {
"field": "catalogId",
"size": 10
},
"aggs": {
"catalog_name_agg": {
"terms": {
"field": "catalogName",
"size": 10
助听器怎么配
}
}
}
},
"attr_agg":{
"nested": {
"path": "attrs"
},
"aggs": {
"attr_id": {
"terms": {
"field": "attrs.attrId",
"size": 10什么是血脂高
},
"aggs": {
"attr_name_id": {
"terms": {
"field": "attrs.attrName", "size": 10
}
}
},
"from": 0,
"size": 2,
"highlight": {
"fields": {"skuTitle": {}},
"pre_tags": "<b style='color:red'>",
"post_tags": "</b>"
}
}
1.2 java代码
在java中使⽤es检索,⽐较重要的⼀个对象是SearchSourceBuilder 1.2.1 不带聚合条件
import com.bjc.fig.GulimallElasticSearchConfig; import com.bjc.stant.EsConstant;
import com.bjc.gulimall.arch.rvice.MallSearchService;
import com.bjc.gulimall.arch.vo.SearchParam;
import com.bjc.gulimall.arch.vo.SearchResult;
slf4j.Slf4j;
import s.lang3.StringUtils;
import org.apache.lucene.arch.join.ScoreMode;
import org.elasticarch.action.arch.SearchRequest;
import org.elasticarch.action.arch.SearchRespon;
import org.elasticarch.client.RestHighLevelClient;
import org.elasticarch.index.query.*;
import org.elasticarch.arch.builder.SearchSourceBuilder;
import org.elasticarch.arch.fetch.subpha.highlight.HighlightBuilder; import org.elasticarch.arch.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@Service
@Slf4j
public class MallSearchServiceImpl implements MallSearchService {
@Autowired
private RestHighLevelClient client;
/*
* 根据检索参数返回检索结果
* SearchResult 包含页⾯需要的所有信息
* */
@Override
public SearchResult arch(SearchParam archParam) {
SearchResult result = null;
/*
* 1. 动态构建出查询需要的DSL语句
* */
// 1.1 创建检索请求对象
// SearchRequest archRequest = new SearchRequest();
SearchRequest archRequest = buildSearchRequest(archParam);
/* 2. 执⾏检索请求 */
SearchRespon respon = client.arch(archRequest, GulimallElasticSearchConfigMON_OPTIONS);
/* 3. 分析响应数据,封装成指定的数据格式 */
result = buildSearchResult(respon);
} catch (Exception e) {
<("动态构建出查询需要的DSL语句出错,原因:",e);
}
return null;
}
/* 根据响应构建返回结果对象 */
private SearchResult buildSearchResult(SearchRespon respon) {
return null;
}
/* 准备检索请求
* 关键字模糊匹配、过滤(按照属性、分类、品牌、价格区间),排序,分页,⾼亮,聚合分析
* */
private SearchRequest buildSearchRequest(SearchParam archParam) {
// ⽤于构建DSL语句
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
/*
* 1. 查询部分DSL构建
* */
// 1.1 构建queryBuilder对象。复杂的query是通过bool组合检索的,因此需要构建BoolQueryBuilder对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// 1.2 构建全⽂检索条件must,关键字模糊匹配. 如果页⾯有关键字搜索,才进⾏全⽂模糊检索
if(StringUtils.Keyword())){
// 将按照skuTitle全⽂检索的条件封装到boolQuery中
boolQuery.must(QueryBuilders.matchQuery("skuTitle",Keyword()));
}
// 1.3 构建过滤filter条件
// 1.3.1 按照三级分类id过滤
if(null != Catalog3Id()){
// 三级分类id是精确匹配,⽤term
boolQuery.Query("catalogId",Catalog3Id()));
}
// 1.3.2 按照品牌ID过滤(⽀持多选)
if(!CollectionUtils.BrandId())){
boolQuery.sQuery("brandId",BrandId()));
}
// 1.3.3 按照所有指定的属性进⾏查询
/*
* {
"nested": {
"path": "attrs",
"query": {
"bool": {
"must": [
{
"term": {
"attrs.attrId": {
"value": "15"
}
}
},
"terms": {
"attrs.attrValue": [
"aaa",
"⽩⾊",
"OCE-AN10"
]
}
}
]
}
}
}
}
下雪的夜晚* */
if(!CollectionUtils.Attrs())){
BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
// attrs=1_5⼨:8⼨&attrs=2_8G:16G
String[] s = attrStr.split("_");
// 检索的属性ID
String attrId = s[0];
// 检索的属性ID对应的属性值的数组
String[] attrValues = s[1].split(":");
nestedBoolQuery.Query("attrs.attrId",attrId));
nestedBoolQuery.sQuery("attrs.attrValue",attrValues));
// 每⼀个属性都需要⽣成⼀个嵌⼊式查询
// ScoreMode.None 表⽰不参与评分
NestedQueryBuilder nestedQueryBuilder = stedQuery("attrs", nestedBoolQuery, ScoreMode.None); boolQuery.filter(nestedQueryBuilder);
});初入江湖
}
// 1.3.4 按照库存是否有进⾏查询
boolQuery.Query("hasStock",HasStock() == 1));
国庆节作文300字作文// 1.3.5 按照价格区间进⾏查询
if(StringUtils.SkuPrice())){
// 1_500/_500/500_
/*
* "range": {
"skuPrice": {
"gte": 0.0,
"lte": 20000.0
}
}
* */
int g = 0;
int l = 0;
// 1)构建rangeQueryBuilder对象
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("skuPrice");
// 2)解析查询参数
String[] s = SkuPrice().split("_");
if(s.length == 2){
<(s[0]).lte(s[1]);
} el if(s.length == 1){ // 否则就是单值
SkuPrice().startsWith("_")){
rangeQueryBuilder.lte(s[0]);
} el {
<(s[0]);
}
}
boolQuery.filter(rangeQueryBuilder);
}