ElasticSearch6.0 多字段聚合网上完整的资料很少 ,所以作者经过查阅资料,编写了聚合高级使用例子
例子是根据电商搜索实际场景模拟出来的
希望给大家带来帮助!
下面我们开始吧!
1. 创建索引的映射关系
1 PUT gome_market
2 {
3 "mappings": {
4 "goods": {
5 "dynamic_templates": [
6 {
7 "dynamicFields": {
8 "match_mapping_type": "string",
9 "path_match":"dynamicFields.*_sku_attr",
10 "mapping":{
11 "type": "keyword"
12 }
13 }
14 }
15 ],
16 "properties":{
17 "id":{
18 "type": "keyword"
19 },
20 "category_first_id":{
21 "type": "keyword"
22 },
23 "category_first":{
24 "type": "keyword"
25 },
26 "category_second_id":{
27 "type": "keyword"
28 },
29 "category_second":{
30 "type": "keyword"
31 },
32 "category_third_id":{
33 "type": "keyword"
34 },
35 "category_third":{
36 "type": "keyword"
37 },
38 "brand_id":{
39 "type": "keyword"
40 },
41 "brand":{
42 "type": "text",
43 "analyzer":"ik_max_word",
44 "search_analyzer":"ik_max_word",
45 "copy_to":"full_name"
46 },
47 "shop":{
48 "type": "keyword"
49 },
50 "attr_name":{
51 "type": "keyword",
52 "index":"true"
53
54 },
55 "sku":{
56 "type": "keyword",
57 "index":"true"
58 },
59 "spu":{
60 "type": "keyword",
61 "index":"true"
62 },
63 "gome_sku":{
64 "type": "keyword"
65 },
66 "product_ch":{
67 "type": "text",
68 "analyzer":"ik_max_word",
69 "search_analyzer":"ik_max_word",
70 "copy_to":"full_name"
71 },
72 "adver":{
73 "type": "keyword"
74 },
75 "product_img":{
76 "type": "keyword"
77 },
78 "product_proto_price":{
79 "type": "double"
80 },
81 "product_sale_price":{
82 "type": "double"
83 },
84 "is_sku":{
85 "type": "boolean"
86 },
87 "is_self":{
88 "type": "boolean"
89 },
90 "shop_flag":{
91 "type": "long"
92 },
93 "is_in_store":{
94 "type": "boolean"
95 },
96 "is_shelves":{
97 "type": "boolean"
98 },
99 "is_suit":{
100 "type": "boolean"
101 },
102 "good_comment_rate":{
103 "type": "long"
104 },
105 "sale_num":{
106 "type": "long"
107 },
108 "spu_score":{
109 "type": "long"
110 },
111 "dynamic_attrs":{
112 "type": "keyword"
113 },
114 "full_name":{
115 "type": "text",
116 "store":"true"
117 },
118 "create_time":{
119 "type":"date"
120 }
121 }
122 }
123 }
124 }
2.创建索引数据
请参照上一篇文章
3.Controller层 创建 SuperMarketSearchController
1 package com.elastic.controller;
2
3 import com.alibaba.fastjson.JSONObject;
4
5 import com.elastic.service.inter.SuperMarketSearchService;
6 import com.elastic.service.pojo.SearchBean;
7 import org.apache.commons.lang.StringUtils;
8 import org.apache.log4j.Logger;
9 import org.springframework.stereotype.Controller;
10 import org.springframework.web.bind.annotation.RequestMapping;
11
12 import javax.annotation.Resource;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 import java.io.*;
16 import java.net.URLDecoder;
17 import java.nio.charset.Charset;
18
19 @Controller
20 public class SuperMarketSearchController extends BaseController {
21
22 private static final Logger logger = Logger.getLogger(SuperMarketSearchController.class);
23
24 @Resource(name = "superMarketSearchServiceImpl")
25 private SuperMarketSearchService searchService;
26
27 @RequestMapping(value = "/s.action")
28 public String searchForPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
29 try {
30 String param = getParam(request);
31 logger.info("请求参数:" + param);
32 SearchBean bean = JSONObject.toJavaObject(JSONObject.parseObject(param), SearchBean.class);
33 bean.setQuery(bean.getQuery() != null ? URLDecoder.decode(bean.getQuery(), "UTF-8") : null);
34 String re = searchService.searchByBean(bean);
35 printReturnVal(response, re);
36 } catch (Exception e) {
37 e.printStackTrace();
38 logger.error(e.getMessage());
39 printReturnVal(response, assemReturn("[]", 500, "系统异常,请检查参数:" + e.getMessage()));
40 }
41 return null;
42 }
43
44
45
46 @RequestMapping(value = "/suggest")
47 public void suggest(HttpServletRequest request, HttpServletResponse response) throws Exception {
48 String keyword = request.getParameter("keyword");
49 // String newKeyWord="";
50 // if (!StringUtils.isEmpty(keyword)){
51 // newKeyWord = new String(keyword.getBytes("ISO-8859-1"), "UTF-8");
52 // }
53 SearchBean bean = new SearchBean();
54 // bean.setQuery(newKeyWord==""?"********":newKeyWord);
55 bean.setQuery(keyword);
56 PrintWriter out = null;
57 String suggests = searchService.suggestByBean(bean);
58 printReturnVal(response, suggests);
59 }
60
61 private void printReturnVal(HttpServletResponse response, String returnVal) {
62 PrintWriter out = null;
63 try {
64 response.setCharacterEncoding("UTF-8");
65 response.setContentType("application/json");
66 out = response.getWriter();
67 System.out.println(returnVal);
68 out.print(returnVal);
69 out.flush();
70 } catch (IOException e) {
71 e.printStackTrace();
72 }
73 }
74
75 private String getParam(HttpServletRequest request) throws IOException {
76 StringBuffer sb = new StringBuffer();
77 InputStream is = request.getInputStream();
78 InputStreamReader isr = new InputStreamReader(is, Charset.forName("UTF-8"));
79 BufferedReader br = new BufferedReader(isr);
80 String s = "";
81 while ((s = br.readLine()) != null) {
82 sb.append(s);
83 }
84 isr.close();
85 br.close();
86 String str = sb.toString();
87 logger.info("requstParam=" + str);
88 String param = "";
89 JSONObject jsonObject = JSONObject.parseObject(str);
90 if (jsonObject.getString("body") != null && !jsonObject.getString("body").isEmpty()) {
91 param = jsonObject.getString("body");
92 } else {
93 param = str;
94 }
95 return param;
96 }
97
98 }
4. Service层 interface SuperMarketSearchService
1 package com.elastic.service.inter;
2
3
4 import com.elastic.service.pojo.SearchBean;
5
6 public interface SuperMarketSearchService {
7
8 public String searchByBean(SearchBean bean);
9
10 public String suggestByBean(SearchBean bean);
11
12 }
Service层 Impl 实现 SuperMarketSearchServiceImpl
1 package com.elastic.service.impl;
2
3 import com.elastic.common.conn.EsClient;
4 import com.elastic.service.inter.SuperMarketSearchService;
5 import com.elastic.service.pojo.Filter;
6 import com.elastic.service.pojo.SearchBean;
7 import com.elastic.service.vo.SearchParams;
8 import com.elastic.service.vo.SearchReturn;
9 import com.elastic.util.SpringApplicationUtils;
10 import org.apache.commons.lang.StringUtils;
11 import org.elasticsearch.action.search.SearchRequestBuilder;
12 import org.elasticsearch.action.search.SearchResponse;
13 import org.elasticsearch.client.transport.TransportClient;
14 import org.elasticsearch.index.query.BoolQueryBuilder;
15 import org.elasticsearch.index.query.Operator;
16 import org.elasticsearch.index.query.QueryBuilder;
17 import org.elasticsearch.index.query.QueryBuilders;
18 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
19 import org.elasticsearch.index.query.functionscore.ScriptScoreFunctionBuilder;
20 import org.elasticsearch.script.Script;
21 import org.elasticsearch.script.ScriptType;
22 import org.elasticsearch.search.aggregations.*;
23 import org.elasticsearch.search.aggregations.bucket.filter.InternalFilter;
24 import org.elasticsearch.search.aggregations.bucket.range.Range;
25 import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder;
26 import org.elasticsearch.search.aggregations.bucket.terms.*;
27 import org.springframework.stereotype.Service;
28
29 import java.math.BigDecimal;
30 import java.util.*;
31 import java.util.function.BiConsumer;
32
33 import static org.elasticsearch.index.query.QueryBuilders.functionScoreQuery;
34
35 /**
36 * Created by xiaotian on 2017/12/23.
37 */
38 @Service
39 public class SuperMarketSearchServiceImpl implements SuperMarketSearchService {
40
41 private EsClient esClient;
42
43 @Override
44 public String searchByBean(SearchBean bean) {
45 try {
46 esClient = SpringApplicationUtils.getBean(EsClient.class);
47 SearchRequestBuilder searchRequestBuilder = esClient.getConnection().prepareSearch("gome_market").setTypes("goods");
48 long s = System.currentTimeMillis();
49
50 bean.setIsFacet(bean.getIsFacet() == null ? true : bean.getIsFacet());
51 if (bean.getIsFacet()){
52 //聚合
53 String[] attrFacet = new String[]{"attr_name"};
54 bean.setFacetFields(attrFacet);
55
56 }
57 SearchResponse searchResponse = assemQueryByBean(searchRequestBuilder, esClient, bean);
58
59 bean.setFacetFields(null);
60 if (bean.getIsFacet()){
61 String[] docAttrFields = getDocAttrFields(searchResponse);
62 bean.setFacetFields(docAttrFields);
63 SearchRequestBuilder requestBuilder = esClient.getConnection().prepareSearch("gome_market").setTypes("goods");
64 SearchResponse response = assemQueryByBean(requestBuilder, esClient, bean);
65
66 Aggregations aggregations = response.getAggregations();
67 Map<String, Aggregation> asMap = aggregations.getAsMap();
68 List<String> list = new ArrayList<>();
69 for (String key: bean.getFacetFields()) {
70 InternalFilter filter = aggregations.get(key);
71 Map<String, Aggregation> aggMap = filter.getAggregations().getAsMap();
72 Iterator<String> iterator = filter.getAggregations().getAsMap().keySet().iterator();
73 while (iterator.hasNext()){
74 String keys = iterator.next();
75 if ("range".equals(keys)){
76 continue;
77 }
78 if (aggMap.get(keys)==null|| aggMap.get(keys) instanceof UnmappedTerms){
79 continue;
80 }
81 StringTerms aggregation = (StringTerms)aggMap.get(keys);
82 aggregation.getBuckets().forEach(bucket -> {
83 System.out.println(keys+"-->"+bucket.getKey()+":"+bucket.getDocCount());
84 list.add(keys+"-->"+bucket.getKey()+":"+bucket.getDocCount());
85 });
86
87 }
88 }
89 System.out.println("list="+list);
9
97 Range range = response.getAggregations().get("range");
98
99 range.getBuckets().forEach(bucket ->{
100
102 System.out.println(String.format("key [%s], from [%s], to [%s], doc_count [%d]", bucket.getKey(), bucket.getFrom(),bucket.getTo(),bucket.getDocCount()));
103
104 });
105 }else {
106
107 }
108
109
110 } catch (Exception e) {
111 e.printStackTrace();
112 } finally {
113 }
114
115 return null;
116 }
117
118 private String[] getDocAttrFields(SearchResponse searchResponse) {
119 List<String> attrFieldList = new ArrayList<>();
120 attrFieldList.add("category_third");
121 attrFieldList.add("category_third_id");
122 if (searchResponse.getAggregations().get("attr_name")!=null){
123 InternalFilter aggFilter= searchResponse.getAggregations().get("attr_name");
124 Map<String, Aggregation> aggMap = aggFilter.getAggregations().getAsMap();
125 Iterator<String> iterator = aggFilter.getAggregations().getAsMap().keySet().iterator();
126 while (iterator.hasNext()){
127 String keys = iterator.next();
128 StringTerms aggregation = (StringTerms)aggMap.get(keys);
129 aggregation.getBuckets().forEach(bucket -> {
130 attrFieldList.add("dynamicFields."+bucket.getKey()+"");
131 System.out.println(keys+"-->"+bucket.getKey()+":"+bucket.getDocCount());
132 });
133
134 }
135 }
136
137 return attrFieldList.toArray(new String[attrFieldList.size()]);
138 }
139
140 @Override
141 public String suggestByBean(SearchBean bean) {
142 return null;
143 }
144
145
146 private SearchResponse assemQueryByBean(SearchRequestBuilder searchRequest, EsClient esClient, SearchBean bean) throws Exception {
147
148 Map<String, Object> params = new HashMap<>();
149 params.put("num1", 1);
150 params.put("num2", 2);
151
152 //String inlineScript = "long age;if (doc['age'].value < 45) age = doc['age'].value + 50; return age * params.num1;";
153 String inlineScript = " return doc['age'].value * params.num1;";
154 // + "return (diff +num1+num2)";
155 Script script = new Script(ScriptType.INLINE,"painless",inlineScript , params);
156 ScriptScoreFunctionBuilder scriptScoreFunctionBuilder = ScoreFunctionBuilders.scriptFunction(script);
157 //searchRequest.setQuery(functionScoreQuery(QueryBuilders.matchQuery("name","中华").operator(Operator.AND),scriptScoreFunctionBuilder));
158 searchRequest.setQuery(bean.getQuery()!=null?QueryBuilders.matchQuery("full_name",bean.getQuery()):QueryBuilders.matchAllQuery());
159
160 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
161 BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
162 //条件
163 boolQueryBuilder.must(queryBuilder);
164 //动态添加聚合项目
165 if (bean.getFacetFields()!=null){
166
167 for (String field : bean.getFacetFields()) {
168 TermsAggregationBuilder aggFieldBuilder = AggregationBuilders.terms(field).field(field);
169 aggFieldBuilder.size(1000);
170 AggregationBuilder filter = AggregationBuilders.filter(field, boolQueryBuilder);
171 filter.subAggregation(aggFieldBuilder);
172 searchRequest.addAggregation(filter);
173 }
174 }
175
176
177 RangeAggregationBuilder rangeAggregationBuilder = AggregationBuilders.range("range").field("product_sale_price").addRange(0, 30).addRange(30,50).addRange(50,100);
178 searchRequest.addAggregation(rangeAggregationBuilder);
179 searchRequest.setPostFilter(boolQueryBuilder);
180 searchRequest.setFrom(0);
181 searchRequest.setSize(10);
182 searchRequest.setExplain(true);
183 System.out.println("param:"+searchRequest);
184 SearchResponse searchResponse = searchRequest.get();
185 return searchResponse;
186
187 }
188
189 private QueryBuilder getFilterQuery(String fieldName, Object[] fieldValues, String andor, BoolQueryBuilder queryBuilder) {
190 //BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
191
192 for (int i = 0; i < fieldValues.length; i++) {
193 if ("OR".equals(andor)){
194 queryBuilder.should(QueryBuilders.matchQuery(fieldName,fieldValues[i]).operator(Operator.OR));
195 }else if ("AND".equals(andor)){
196 queryBuilder.must(QueryBuilders.matchQuery(fieldName,fieldValues[i]).operator(Operator.AND));
197 }
198 }
199
200 return queryBuilder;
201
202 }
203
204 private void assemQueryParam(SearchBean bean, SearchReturn returns) {
205 SearchParams params = new SearchParams();
206 params.setKeyword(bean.getQuery());
207 Filter f = bean.getFilter();
208 if (f != null) {
209 String[] catFirst = f.getCatFirst();
210 String[] catSecond = f.getCatSecond();
211 String[] catThird = f.getCatThird();
212 Integer[] brand = f.getBrand();
213 Integer[] country = f.getCountry();
214 String[] fgCatFirst = f.getFgCatFirst();
215 String[] fgCatSecond = f.getFgCatSecond();
216 String[] fgCatThird = f.getFgCatThird();
217 String[] whiteShopIds = f.getWhiteShopIds();
218 String[] whiteCateIds = f.getWhiteCateIds();
219 String[] whiteBrandIds = f.getWhiteBrandIds();
220 String[] whiteProdIds = f.getWhiteProdIds();
221 String[] blackShopIds = f.getBlackShopIds();
222 String[] blackCateIds = f.getBlackCateIds();
223 String[] blackBrandIds = f.getBlackBrandIds();
224 String[] blackProdIds = f.getBlackProdIds();
225 String[] activityIds = f.getActivityIds();
226
227 if (catFirst != null && catFirst.length > 0) {
228 params.setCatFirst(catFirst);
229 }
230 if (catSecond != null && catSecond.length > 0) {
231 params.setCatSecond(catSecond);
232 }
233 if (catThird != null && catThird.length > 0) {
234 params.setCatThird(catThird);
235 }
236 if (fgCatFirst != null && fgCatFirst.length > 0) {
237 params.setFgCatFirst(fgCatFirst);
238 }
239 if (fgCatSecond != null && fgCatSecond.length > 0) {
240 params.setFgCatSecond(fgCatSecond);
241 }
242 if (fgCatThird != null && fgCatThird.length > 0) {
243 params.setFgCatThird(fgCatThird);
244 }
245 if (brand != null && brand.length > 0) {
246 params.setBrand(brand);
247 }
248 if (country != null && country.length > 0) {
249 params.setCountry(country);
250 }
251 if (activityIds!=null&&activityIds.length>0){
252 params.setActivityIds(activityIds);
253 }
254 }
255 returns.setSearchParams(params);
256 }
257 }
5.通过kibana查询结果
查询条件 : 跟java执行是一样的参数
1 GET gome_market/_search
2 {
3 "from" : 0,
4 "size" : 10,
5 "query" : {
6 "match" : {
7 "full_name" : {
8 "query" : "多颜色多版本",
9 "operator" : "OR",
10 "prefix_length" : 0,
11 "max_expansions" : 50,
12 "fuzzy_transpositions" : true,
13 "lenient" : false,
14 "zero_terms_query" : "NONE",
15 "boost" : 1.0
16 }
17 }
18 },
19 "post_filter" : {
20 "bool" : {
21 "must" : [
22 {
23 "bool" : {
24 "adjust_pure_negative" : true,
25 "boost" : 1.0
26 }
27 }
28 ],
29 "adjust_pure_negative" : true,
30 "boost" : 1.0
31 }
32 },
33 "explain" : true,
34 "aggregations" : {
35 "category_third" : {
36 "filter" : {
37 "bool" : {
38 "must" : [
39 {
40 "bool" : {
41 "adjust_pure_negative" : true,
42 "boost" : 1.0
43 }
44 }
45 ],
46 "adjust_pure_negative" : true,
47 "boost" : 1.0
48 }
49 },
50 "aggregations" : {
51 "category_third" : {
52 "terms" : {
53 "field" : "category_third",
54 "size" : 1000,
55 "min_doc_count" : 1,
56 "shard_min_doc_count" : 0,
57 "show_term_doc_count_error" : false,
58 "order" : [
59 {
60 "_count" : "desc"
61 },
62 {
63 "_key" : "asc"
64 }
65 ]
66 }
67 }
68 }
69 },
70 "category_third_id" : {
71 "filter" : {
72 "bool" : {
73 "must" : [
74 {
75 "bool" : {
76 "adjust_pure_negative" : true,
77 "boost" : 1.0
78 }
79 }
80 ],
81 "adjust_pure_negative" : true,
82 "boost" : 1.0
83 }
84 },
85 "aggregations" : {
86 "category_third_id" : {
87 "terms" : {
88 "field" : "category_third_id",
89 "size" : 1000,
90 "min_doc_count" : 1,
91 "shard_min_doc_count" : 0,
92 "show_term_doc_count_error" : false,
93 "order" : [
94 {
95 "_count" : "desc"
96 },
97 {
98 "_key" : "asc"
99 }
100 ]
101 }
102 }
103 }
104 },
105 "dynamicFields.sku级多选_sku_attr" : {
106 "filter" : {
107 "bool" : {
108 "must" : [
109 {
110 "bool" : {
111 "adjust_pure_negative" : true,
112 "boost" : 1.0
113 }
114 }
115 ],
116 "adjust_pure_negative" : true,
117 "boost" : 1.0
118 }
119 },
120 "aggregations" : {
121 "dynamicFields.sku级多选_sku_attr" : {
122 "terms" : {
123 "field" : "dynamicFields.sku级多选_sku_attr",
124 "size" : 1000,
125 "min_doc_count" : 1,
126 "shard_min_doc_count" : 0,
127 "show_term_doc_count_error" : false,
128 "order" : [
129 {
130 "_count" : "desc"
131 },
132 {
133 "_key" : "asc"
134 }
135 ]
136 }
137 }
138 }
139 },
140 "dynamicFields.sku级枚举_sku_attr" : {
141 "filter" : {
142 "bool" : {
143 "must" : [
144 {
145 "bool" : {
146 "adjust_pure_negative" : true,
147 "boost" : 1.0
148 }
149 }
150 ],
151 "adjust_pure_negative" : true,
152 "boost" : 1.0
153 }
154 },
155 "aggregations" : {
156 "dynamicFields.sku级枚举_sku_attr" : {
157 "terms" : {
158 "field" : "dynamicFields.sku级枚举_sku_attr",
159 "size" : 1000,
160 "min_doc_count" : 1,
161 "shard_min_doc_count" : 0,
162 "show_term_doc_count_error" : false,
163 "order" : [
164 {
165 "_count" : "desc"
166 },
167 {
168 "_key" : "asc"
169 }
170 ]
171 }
172 }
173 }
174 },
175 "dynamicFields.品牌_sku_attr" : {
176 "filter" : {
177 "bool" : {
178 "must" : [
179 {
180 "bool" : {
181 "adjust_pure_negative" : true,
182 "boost" : 1.0
183 }
184 }
185 ],
186 "adjust_pure_negative" : true,
187 "boost" : 1.0
188 }
189 },
190 "aggregations" : {
191 "dynamicFields.品牌_sku_attr" : {
192 "terms" : {
193 "field" : "dynamicFields.品牌_sku_attr",
194 "size" : 1000,
195 "min_doc_count" : 1,
196 "shard_min_doc_count" : 0,
197 "show_term_doc_count_error" : false,
198 "order" : [
199 {
200 "_count" : "desc"
201 },
202 {
203 "_key" : "asc"
204 }
205 ]
206 }
207 }
208 }
209 },
210 "dynamicFields.类别-模板2使用_sku_attr" : {
211 "filter" : {
212 "bool" : {
213 "must" : [
214 {
215 "bool" : {
216 "adjust_pure_negative" : true,
217 "boost" : 1.0
218 }
219 }
220 ],
221 "adjust_pure_negative" : true,
222 "boost" : 1.0
223 }
224 },
225 "aggregations" : {
226 "dynamicFields.类别-模板2使用_sku_attr" : {
227 "terms" : {
228 "field" : "dynamicFields.类别-模板2使用_sku_attr",
229 "size" : 1000,
230 "min_doc_count" : 1,
231 "shard_min_doc_count" : 0,
232 "show_term_doc_count_error" : false,
233 "order" : [
234 {
235 "_count" : "desc"
236 },
237 {
238 "_key" : "asc"
239 }
240 ]
241 }
242 }
243 }
244 },
245 "dynamicFields.颜色-模板2使用_sku_attr" : {
246 "filter" : {
247 "bool" : {
248 "must" : [
249 {
250 "bool" : {
251 "adjust_pure_negative" : true,
252 "boost" : 1.0
253 }
254 }
255 ],
256 "adjust_pure_negative" : true,
257 "boost" : 1.0
258 }
259 },
260 "aggregations" : {
261 "dynamicFields.颜色-模板2使用_sku_attr" : {
262 "terms" : {
263 "field" : "dynamicFields.颜色-模板2使用_sku_attr",
264 "size" : 1000,
265 "min_doc_count" : 1,
266 "shard_min_doc_count" : 0,
267 "show_term_doc_count_error" : false,
268 "order" : [
269 {
270 "_count" : "desc"
271 },
272 {
273 "_key" : "asc"
274 }
275 ]
276 }
277 }
278 }
279 },
280 "range" : {
281 "range" : {
282 "field" : "product_sale_price",
283 "ranges" : [
284 {
285 "from" : 0.0,
286 "to" : 30.0
287 },
288 {
289 "from" : 30.0,
290 "to" : 50.0
291 },
292 {
293 "from" : 50.0,
294 "to" : 100.0
295 }
296 ],
297 "keyed" : false
298 }
299 }
300 }
301 }
查询结果:
1 {
2 "took": 9,
3 "timed_out": false,
4 "_shards": {
5 "total": 5,
6 "successful": 5,
7 "skipped": 0,
8 "failed": 0
9 },
10 "hits": {
11 "total": 3,
12 "max_score": 4.531806,
13 "hits": [
14 {
15 "_shard": "[gome_market][0]",
16 "_node": "WBp9VADzRG2Jr-yIKi8h6w",
17 "_index": "gome_market",
18 "_type": "goods",
19 "_id": "100253641",
20 "_score": 4.531806,
21 "_source": {
22 "is_shelves": false,
23 "shop_flag": 2,
24 "category_third": "536_耳机/耳麦",
25 "shop": "",
26 "product_ch": "zyl-多颜色多版本",
27 "spu_score": 0,
28 "category_second": "311_时尚数码",
29 "category_third_id": "536",
30 "id": "100253641",
31 "is_in_store": false,
32 "sku": "100253641",
33 "brand": "10000073_诺基亚(NOKIA)",
34 "is_self": false,
35 "is_suit": false,
36 "product_proto_price": 0,
37 "create_time": "2017-12-25T07:20:37.510Z",
38 "good_comment_rate": 0,
39 "sale_num": 0,
40 "adver": "",
41 "attr_name": [
42 "品牌_sku_attr",
43 "颜色-模板2使用_sku_attr",
44 "类别-模板2使用_sku_attr",
45 "sku级枚举_sku_attr",
46 "sku级多选_sku_attr"
47 ],
48 "category_first_id": "286",
49 "is_sku": true,
50 "dynamicFields": {
51 "品牌_sku_attr": [
52 "诺基亚(NOKIA)"
53 ],
54 "颜色-模板2使用_sku_attr": [
55 "黑色"
56 ],
57 "适用人群-模板2使用_sku_attr": [
58 "人群"
59 ],
60 "类别-模板2使用_sku_attr": [
61 "手提包, 洗漱包"
62 ]
63 },
64 "brand_id": 10000073,
65 "product_img": "//gfs17.atguat.net.cn/T1.FKTBvVT1RCvBVdK",
66 "product_sale_price": 2223,
67 "category_first": "286_数码",
68 "shop_id": "null",
69 "category_second_id": "311",
70 "gome_sku": "1000101403",
71 "spu": "9010006069"
72 },
73 "_explanation": {
74 "value": 4.531806,
75 "description": "sum of:",
76 "details": [
77 {
78 "value": 0.9293165,
79 "description": "weight(full_name:多 in 0) [PerFieldSimilarity], result of:",
80 "details": [
81 {
82 "value": 0.9293165,
83 "description": "score(doc=0,freq=2.0 = termFreq=2.0\n), product of:",
84 "details": [
85 {
86 "value": 0.6931472,
87 "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
88 "details": [
89 {
90 "value": 1,
91 "description": "docFreq",
92 "details": []
93 },
94 {
95 "value": 2,
96 "description": "docCount",
97 "details": []
98 }
99 ]
100 },
101 {
102 "value": 1.3407203,
103 "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
104 "details": [
105 {
106 "value": 2,
107 "description": "termFreq=2.0",
108 "details": []
109 },
110 {
111 "value": 1.2,
112 "description": "parameter k1",
113 "details": []
114 },
115 {
116 "value": 0.75,
117 "description": "parameter b",
118 "details": []
119 },
120 {
121 "value": 11,
122 "description": "avgFieldLength",
123 "details": []
124 },
125 {
126 "value": 12,
127 "description": "fieldLength",
128 "details": []
129 }
130 ]
131 }
132 ]
133 }
134 ]
135 },
136 {
137 "value": 0.6682933,
138 "description": "weight(full_name:颜 in 0) [PerFieldSimilarity], result of:",
139 "details": [
140 {
141 "value": 0.6682933,
142 "description": "score(doc=0,freq=1.0 = termFreq=1.0\n), product of:",
143 "details": [
144 {
145 "value": 0.6931472,
146 "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
147 "details": [
148 {
149 "value": 1,
150 "description": "docFreq",
151 "details": []
152 },
153 {
154 "value": 2,
155 "description": "docCount",
156 "details": []
157 }
158 ]
159 },
160 {
161 "value": 0.96414346,
162 "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
163 "details": [
164 {
165 "value": 1,
166 "description": "termFreq=1.0",
167 "details": []
168 },
169 {
170 "value": 1.2,
171 "description": "parameter k1",
172 "details": []
173 },
174 {
175 "value": 0.75,
176 "description": "parameter b",
177 "details": []
178 },
179 {
180 "value": 11,
181 "description": "avgFieldLength",
182 "details": []
183 },
184 {
185 "value": 12,
186 "description": "fieldLength",
187 "details": []
188 }
189 ]
190 }
191 ]
192 }
193 ]
194 },
195 {
196 "value": 0.6682933,
197 "description": "weight(full_name:色 in 0) [PerFieldSimilarity], result of:",
198 "details": [
199 {
200 "value": 0.6682933,
201 "description": "score(doc=0,freq=1.0 = termFreq=1.0\n), product of:",
202 "details": [
203 {
204 "value": 0.6931472,
205 "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
206 "details": [
207 {
208 "value": 1,
209 "description": "docFreq",
210 "details": []
211 },
212 {
213 "value": 2,
214 "description": "docCount",
215 "details": []
216 }
217 ]
218 },
219 {
220 "value": 0.96414346,
221 "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
222 "details": [
223 {
224 "value": 1,
225 "description": "termFreq=1.0",
226 "details": []
227 },
228 {
229 "value": 1.2,
230 "description": "parameter k1",
231 "details": []
232 },
233 {
234 "value": 0.75,
235 "description": "parameter b",
236 "details": []
237 },
238 {
239 "value": 11,
240 "description": "avgFieldLength",
241 "details": []
242 },
243 {
244 "value": 12,
245 "description": "fieldLength",
246 "details": []
247 }
248 ]
249 }
250 ]
251 }
252 ]
253 },
254 {
255 "value": 0.9293165,
256 "description": "weight(full_name:多 in 0) [PerFieldSimilarity], result of:",
257 "details": [
258 {
259 "value": 0.9293165,
260 "description": "score(doc=0,freq=2.0 = termFreq=2.0\n), product of:",
261 "details": [
262 {
263 "value": 0.6931472,
264 "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
265 "details": [
266 {
267 "value": 1,
268 "description": "docFreq",
269 "details": []
270 },
271 {
272 "value": 2,
273 "description": "docCount",
274 "details": []
275 }
276 ]
277 },
278 {
279 "value": 1.3407203,
280 "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
281 "details": [
282 {
283 "value": 2,
284 "description": "termFreq=2.0",
285 "details": []
286 },
287 {
288 "value": 1.2,
289 "description": "parameter k1",
290 "details": []
291 },
292 {
293 "value": 0.75,
294 "description": "parameter b",
295 "details": []
296 },
297 {
298 "value": 11,
299 "description": "avgFieldLength",
300 "details": []
301 },
302 {
303 "value": 12,
304 "description": "fieldLength",
305 "details": []
306 }
307 ]
308 }
309 ]
310 }
311 ]
312 },
313 {
314 "value": 0.6682933,
315 "description": "weight(full_name:版 in 0) [PerFieldSimilarity], result of:",
316 "details": [
317 {
318 "value": 0.6682933,
319 "description": "score(doc=0,freq=1.0 = termFreq=1.0\n), product of:",
320 "details": [
321 {
322 "value": 0.6931472,
323 "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
324 "details": [
325 {
326 "value": 1,
327 "description": "docFreq",
328 "details": []
329 },
330 {
331 "value": 2,
332 "description": "docCount",
333 "details": []
334 }
335 ]
336 },
337 {
338 "value": 0.96414346,
339 "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
340 "details": [
341 {
342 "value": 1,
343 "description": "termFreq=1.0",
344 "details": []
345 },
346 {
347 "value": 1.2,
348 "description": "parameter k1",
349 "details": []
350 },
351 {
352 "value": 0.75,
353 "description": "parameter b",
354 "details": []
355 },
356 {
357 "value": 11,
358 "description": "avgFieldLength",
359 "details": []
360 },
361 {
362 "value": 12,
363 "description": "fieldLength",
364 "details": []
365 }
366 ]
367 }
368 ]
369 }
370 ]
371 },
372 {
373 "value": 0.6682933,
374 "description": "weight(full_name:本 in 0) [PerFieldSimilarity], result of:",
375 "details": [
376 {
377 "value": 0.6682933,
378 "description": "score(doc=0,freq=1.0 = termFreq=1.0\n), product of:",
379 "details": [
380 {
381 "value": 0.6931472,
382 "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
383 "details": [
384 {
385 "value": 1,
386 "description": "docFreq",
387 "details": []
388 },
389 {
390 "value": 2,
391 "description": "docCount",
392 "details": []
393 }
394 ]
395 },
396 {
397 "value": 0.96414346,
398 "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
399 "details": [
400 {
401 "value": 1,
402 "description": "termFreq=1.0",
403 "details": []
404 },
405 {
406 "value": 1.2,
407 "description": "parameter k1",
408 "details": []
409 },
410 {
411 "value": 0.75,
412 "description": "parameter b",
413 "details": []
414 },
415 {
416 "value": 11,
417 "description": "avgFieldLength",
418 "details": []
419 },
420 {
421 "value": 12,
422 "description": "fieldLength",
423 "details": []
424 }
425 ]
426 }
427 ]
428 }
429 ]
430 }
431 ]
432 }
433 },
434 {
435 "_shard": "[gome_market][1]",
436 "_node": "WBp9VADzRG2Jr-yIKi8h6w",
437 "_index": "gome_market",
438 "_type": "goods",
439 "_id": "1000122353",
440 "_score": 0.2876821,
441 "_source": {
442 "is_shelves": false,
443 "shop_flag": 2,
444 "category_third": "536_耳机/耳麦",
445 "shop": "",
446 "product_ch": "诺基亚(NOKIA)C5-05手机(黑银色)非定制机-------9010006069这个product改的",
447 "spu_score": 0,
448 "category_second": "311_时尚数码",
449 "category_third_id": "536",
450 "id": "1000122353",
451 "is_in_store": true,
452 "sku": "1000122353",
453 "brand": "10000073_诺基亚(NOKIA)",
454 "is_self": false,
455 "is_suit": false,
456 "product_proto_price": 0,
457 "create_time": "2017-12-25T07:20:36.931Z",
458 "good_comment_rate": 0,
459 "sale_num": 0,
460 "adver": "%E7%99%BD%E6%8B%BF009%20%E6%B1%89%E5%AD%97",
461 "attr_name": [
462 "品牌_sku_attr",
463 "颜色-模板2使用_sku_attr",
464 "类别-模板2使用_sku_attr",
465 "sku级枚举_sku_attr",
466 "sku级多选_sku_attr"
467 ],
468 "category_first_id": "286",
469 "is_sku": true,
470 "dynamicFields": {
471 "sku级枚举_sku_attr": [
472 "洁厕剂"
473 ],
474 "sku级多选_sku_attr": [
475 "中端高性价比"
476 ],
477 "品牌_sku_attr": [
478 "诺基亚(NOKIA)"
479 ],
480 "cy-屏幕尺寸_sku_attr": [
481 "测试测试"
482 ],
483 "0122-cy-多选使用_sku_attr": [
484 "手柄可折叠"
485 ],
486 "0121-cy-枚举使用_sku_attr": [
487 "1千米"
488 ],
489 "0121-cy-多选使用_sku_attr": [
490 "5ml及以下"
491 ],
492 "product级枚举_sku_attr": [
493 "可组合"
494 ],
495 "product级描述_sku_attr": [
496 "测试"
497 ]
498 },
499 "brand_id": 10000073,
500 "product_img": "//gfs11.atguat.net.cn/T1jzhTByY_1RCvBVdK",
501 "product_sale_price": 1311,
502 "category_first": "286_数码",
503 "shop_id": "null",
504 "category_second_id": "311",
505 "gome_sku": "1000046768",
506 "spu": "9010006069"
507 },
508 "_explanation": {
509 "value": 0.2876821,
510 "description": "sum of:",
511 "details": [
512 {
513 "value": 0.2876821,
514 "description": "weight(full_name:色 in 0) [PerFieldSimilarity], result of:",
515 "details": [
516 {
517 "value": 0.2876821,
518 "description": "score(doc=0,freq=1.0 = termFreq=1.0\n), product of:",
519 "details": [
520 {
521 "value": 0.2876821,
522 "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
523 "details": [
524 {
525 "value": 1,
526 "description": "docFreq",
527 "details": []
528 },
529 {
530 "value": 1,
531 "description": "docCount",
532 "details": []
533 }
534 ]
535 },
536 {
537 "value": 1,
538 "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
539 "details": [
540 {
541 "value": 1,
542 "description": "termFreq=1.0",
543 "details": []
544 },
545 {
546 "value": 1.2,
547 "description": "parameter k1",
548 "details": []
549 },
550 {
551 "value": 0.75,
552 "description": "parameter b",
553 "details": []
554 },
555 {
556 "value": 26,
557 "description": "avgFieldLength",
558 "details": []
559 },
560 {
561 "value": 26,
562 "description": "fieldLength",
563 "details": []
564 }
565 ]
566 }
567 ]
568 }
569 ]
570 }
571 ]
572 }
573 },
574 {
575 "_shard": "[gome_market][3]",
576 "_node": "WBp9VADzRG2Jr-yIKi8h6w",
577 "_index": "gome_market",
578 "_type": "goods",
579 "_id": "1000122354",
580 "_score": 0.2876821,
581 "_source": {
582 "is_shelves": false,
583 "shop_flag": 2,
584 "category_third": "536_耳机/耳麦",
585 "shop": "",
586 "product_ch": "诺基亚(NOKIA)C5-05手机(黑红色)searchadmin",
587 "spu_score": 0,
588 "category_second": "311_时尚数码",
589 "category_third_id": "536",
590 "id": "1000122354",
591 "is_in_store": true,
592 "sku": "1000122354",
593 "brand": "10000073_诺基亚(NOKIA)",
594 "is_self": false,
595 "is_suit": false,
596 "product_proto_price": 0,
597 "create_time": "2017-12-25T07:20:38.606Z",
598 "good_comment_rate": 0,
599 "sale_num": 0,
600 "adver": "%E9%95%BF%E6%9C%9F%E4%BF%83%E9%94%80%E8%AF%AD",
601 "attr_name": [
602 "品牌_sku_attr",
603 "颜色-模板2使用_sku_attr",
604 "类别-模板2使用_sku_attr",
605 "sku级枚举_sku_attr",
606 "sku级多选_sku_attr"
607 ],
608 "category_first_id": "286",
609 "is_sku": true,
610 "dynamicFields": {
611 "品牌_sku_attr": [
612 "诺基亚(NOKIA)"
613 ],
614 "颜色-模板2使用_sku_attr": [
615 "黑色"
616 ],
617 "适用人群-模板2使用_sku_attr": [
618 "人群"
619 ],
620 "类别-模板2使用_sku_attr": [
621 "马夹包, 腰挂, 手提包, 洗漱包, 化妆包, 折叠包, 其他"
622 ]
623 },
624 "brand_id": 10000073,
625 "product_img": "//gfs17.atguat.net.cn/T1hNJTB5Av1RCvBVdK",
626 "product_sale_price": 849,
627 "category_first": "286_数码",
628 "shop_id": "null",
629 "category_second_id": "311",
630 "gome_sku": "1000046769",
631 "spu": "9010006069"
632 },
633 "_explanation": {
634 "value": 0.2876821,
635 "description": "sum of:",
636 "details": [
637 {
638 "value": 0.2876821,
639 "description": "weight(full_name:色 in 0) [PerFieldSimilarity], result of:",
640 "details": [
641 {
642 "value": 0.2876821,
643 "description": "score(doc=0,freq=1.0 = termFreq=1.0\n), product of:",
644 "details": [
645 {
646 "value": 0.2876821,
647 "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
648 "details": [
649 {
650 "value": 1,
651 "description": "docFreq",
652 "details": []
653 },
654 {
655 "value": 1,
656 "description": "docCount",
657 "details": []
658 }
659 ]
660 },
661 {
662 "value": 1,
663 "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
664 "details": [
665 {
666 "value": 1,
667 "description": "termFreq=1.0",
668 "details": []
669 },
670 {
671 "value": 1.2,
672 "description": "parameter k1",
673 "details": []
674 },
675 {
676 "value": 0.75,
677 "description": "parameter b",
678 "details": []
679 },
680 {
681 "value": 17,
682 "description": "avgFieldLength",
683 "details": []
684 },
685 {
686 "value": 17,
687 "description": "fieldLength",
688 "details": []
689 }
690 ]
691 }
692 ]
693 }
694 ]
695 }
696 ]
697 }
698 }
699 ]
700 },
701 "aggregations": {
702 "dynamicFields.sku级枚举_sku_attr": {
703 "doc_count": 3,
704 "dynamicFields.sku级枚举_sku_attr": {
705 "doc_count_error_upper_bound": 0,
706 "sum_other_doc_count": 0,
707 "buckets": [
708 {
709 "key": "洁厕剂",
710 "doc_count": 1
711 }
712 ]
713 }
714 },
715 "dynamicFields.类别-模板2使用_sku_attr": {
716 "doc_count": 3,
717 "dynamicFields.类别-模板2使用_sku_attr": {
718 "doc_count_error_upper_bound": 0,
719 "sum_other_doc_count": 0,
720 "buckets": [
721 {
722 "key": "手提包, 洗漱包",
723 "doc_count": 1
724 },
725 {
726 "key": "马夹包, 腰挂, 手提包, 洗漱包, 化妆包, 折叠包, 其他",
727 "doc_count": 1
728 }
729 ]
730 }
731 },
732 "category_third_id": {
733 "doc_count": 3,
734 "category_third_id": {
735 "doc_count_error_upper_bound": 0,
736 "sum_other_doc_count": 0,
737 "buckets": [
738 {
739 "key": "536",
740 "doc_count": 3
741 }
742 ]
743 }
744 },
745 "category_third": {
746 "doc_count": 3,
747 "category_third": {
748 "doc_count_error_upper_bound": 0,
749 "sum_other_doc_count": 0,
750 "buckets": [
751 {
752 "key": "536_耳机/耳麦",
753 "doc_count": 3
754 }
755 ]
756 }
757 },
758 "dynamicFields.sku级多选_sku_attr": {
759 "doc_count": 3,
760 "dynamicFields.sku级多选_sku_attr": {
761 "doc_count_error_upper_bound": 0,
762 "sum_other_doc_count": 0,
763 "buckets": [
764 {
765 "key": "中端高性价比",
766 "doc_count": 1
767 }
768 ]
769 }
770 },
771 "dynamicFields.品牌_sku_attr": {
772 "doc_count": 3,
773 "dynamicFields.品牌_sku_attr": {
774 "doc_count_error_upper_bound": 0,
775 "sum_other_doc_count": 0,
776 "buckets": [
777 {
778 "key": "诺基亚(NOKIA)",
779 "doc_count": 3
780 }
781 ]
782 }
783 },
784 "range": {
785 "buckets": [
786 {
787 "key": "0.0-30.0",
788 "from": 0,
789 "to": 30,
790 "doc_count": 0
791 },
792 {
793 "key": "30.0-50.0",
794 "from": 30,
795 "to": 50,
796 "doc_count": 0
797 },
798 {
799 "key": "50.0-100.0",
800 "from": 50,
801 "to": 100,
802 "doc_count": 0
803 }
804 ]
805 },
806 "dynamicFields.颜色-模板2使用_sku_attr": {
807 "doc_count": 3,
808 "dynamicFields.颜色-模板2使用_sku_attr": {
809 "doc_count_error_upper_bound": 0,
810 "sum_other_doc_count": 0,
811 "buckets": [
812 {
813 "key": "黑色",
814 "doc_count": 2
815 }
816 ]
817 }
818 }
819 }
820 }