ElasticSearch。
获取文档记录。
查询条件:
需要分词的字段 | sku名称 sku描述 | 分词、定义分词器 |
有可能用于过滤的字段 | 平台属性、三级分类、价格 | 要索引 |
其他需要显示的字段 | skuId 图片路径 | 不索引 |
封装elasticsearch的数据结构
public class PmsSearchSkuInfo implements Serializable {
@Id
private String id; /*id*/
private String skuName; /*名称*/
private String skuDesc; /*描述*/
private String catalog3Id; /*三级分类id*/
private String price; /*价格*/
private String skuDefaultImg; /*图片*/
private double hotScore; /*热度*/
private String productId; /*spuid*/
private List<PmsSkuAttrValue> pmsSkuAttrValue; /*sku销售属性*/
}
封装搜索参数
public class PmsSearchParam implements Serializable {
private String catalog3Id;
private String keyword;
private String[] valueId;
}
指定索引的数据结构
PUT gmall
{
"mappings": {
"SkuInfo":{
"properties": {
"id":{
"type": "keyword"
, "index": false
},
"price":{
"type": "double"
},
"skuName":{
"type": "text",
"analyzer": "ik_max_word"
},
"skuDesc":{
"type": "text",
"analyzer": "ik_smart"
},
"catalog3Id":{
"type": "keyword"
},
"skuDefaultImg":{
"type": "keyword",
"index": false
},
"skuAttrValueList":{
"properties": {
"valueId":{
"type":"keyword"
}
}
}
}
}
}
}
查询结果:
- sku的列表(关键词高亮)
- sku设计了哪些属性和属性值
- 命中个数,用于分页;
GET gmall/SkuInfo/_search
{
"query": {
"bool": {
"filter": [
{"terms":{ "skuAttrValueList.valueId": ["46","45"]}},
{"term":{"catalog3Id":"61"}}
],
"must":
{ "match": { "skuName": "128" } }
}
}
, "highlight": {
"fields": {"skuName":{}}
},
"from": 3,
"size": 1,
"sort":{"hotScore":{"order":"desc"}},
"aggs": {
"groupby_attr": {
"terms": {
"field": "skuAttrValueList.valueId"
}
}
}
}
jest客户端包,方便组合复杂的查询json;
Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 它支持构建更加复杂和健壮的查询。官网
@Override
public List<PmsSearchSkuInfo> list(PmsSearchParam pmsSearchParam){
String dslStr = getSearchDsl(pmsSearchParam);
System.err.println(dslStr);
/*用api执行复杂查询*/
List<PmsSearchSkuInfo> pmsSearchSkuInfos = new ArrayList<>();
Search search = new Search.Builder(dslStr).addIndex("gmall0105").addType("PmsSkuInfo").build();
SearchResult execute = null;
try {
execute = jestClient.execute(search);
} catch (IOException e) {
e.printStackTrace();
}
List<SearchResult.Hit<PmsSearchSkuInfo, Void>> hits = execute.getHits(PmsSearchSkuInfo.class);
for (SearchResult.Hit<PmsSearchSkuInfo, Void> hit : hits) {
PmsSearchSkuInfo pmsSearchSkuInfo = hit.source;
/*替换高亮关键字*/
Map<String, List<String>> highlight = hit.highlight;
/*当不用关键字搜索时,Map<String, List<String>> highlight = hit.highlight;
* 得到空的highlight,为了防止highlight.get("skuName").get(0);出现空指针异常
* */
if (highlight!=null){
String skuName = highlight.get("skuName").get(0);
pmsSearchSkuInfo.setSkuName(skuName);
}
pmsSearchSkuInfos.add(pmsSearchSkuInfo);
}
System.out.println(pmsSearchSkuInfos.size());
return pmsSearchSkuInfos;
}
private String getSearchDsl(PmsSearchParam pmsSearchParam) {
String[] valueId = pmsSearchParam.getValueId();
String keyword = pmsSearchParam.getKeyword();
String catalog3Id = pmsSearchParam.getCatalog3Id();
/*jest的dsl工具*/
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
/*bool*/
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
/*filter , 在filter里面可以加term , 相当于"pmsSkuAttrValue.valueId":"2" , 多个term可以new一个TermsQueryBuilder*/
if (!StringUtils.isEmpty(catalog3Id)){
TermQueryBuilder termQueryBuilder = new TermQueryBuilder("catalog3Id" , catalog3Id);
boolQueryBuilder.filter(termQueryBuilder);
}
if (valueId!=null){
for (String skuAttrValue : valueId) {
TermQueryBuilder termQueryBuilder = new TermQueryBuilder("pmsSkuAttrValue.valueId" , skuAttrValue);
boolQueryBuilder.filter(termQueryBuilder);
}
}
/*must , 在must里面可以加match , 相当于"skuName": "P30Pro"*/
if (!StringUtils.isEmpty(keyword)){
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("skuName" , keyword);
boolQueryBuilder.must(matchQueryBuilder);
}
/*query*/
searchSourceBuilder.query(boolQueryBuilder);
/*from*/
searchSourceBuilder.from(0);
/*size*/
searchSourceBuilder.size(20);
/*highlight ,关键字高亮显示*/
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<span style='color:red;'>");
highlightBuilder.field("skuName");
highlightBuilder.postTags("</span>");
searchSourceBuilder.highlight(highlightBuilder);
/*sort排序 , 按照id升序 , 降序 ,这里存在String与long类型转换问题,待解决*/
searchSourceBuilder.sort("id" , SortOrder.DESC);
/*最后转化成String返回给前台*/
return searchSourceBuilder.toString();
}