Authored by zhaojun2

Merge branch 'zj_productanalysis' into 0710

1 package com.yoho.search.cache.beans; 1 package com.yoho.search.cache.beans;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.serializer.SerializerFeature;
4 import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder; 5 import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
5 import com.yoho.search.base.utils.MD5Util; 6 import com.yoho.search.base.utils.MD5Util;
6 import com.yoho.search.cache.impls.EhCache; 7 import com.yoho.search.cache.impls.EhCache;
@@ -77,7 +78,7 @@ public abstract class AbstractCacheComponent<T> { @@ -77,7 +78,7 @@ public abstract class AbstractCacheComponent<T> {
77 if (!useRedis()) { 78 if (!useRedis()) {
78 return; 79 return;
79 } 80 }
80 - String jsonString = JSON.toJSONString(result); 81 + String jsonString = JSON.toJSONString(result, SerializerFeature.WriteMapNullValue,SerializerFeature.DisableCircularReferenceDetect);
81 CacheObject toCacheResult = new CacheObject(jsonString); 82 CacheObject toCacheResult = new CacheObject(jsonString);
82 searchRedis.addOrUpdate(redisKeyBuilder, toCacheResult, this.cacheTimeInMinute()); 83 searchRedis.addOrUpdate(redisKeyBuilder, toCacheResult, this.cacheTimeInMinute());
83 } 84 }
1 package com.yoho.search.cache.beans; 1 package com.yoho.search.cache.beans;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 -import com.alibaba.fastjson.JSONArray;  
5 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
  5 +import com.alibaba.fastjson.serializer.SerializerFeature;
6 import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder; 6 import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
7 import com.yoho.search.base.utils.MD5Util; 7 import com.yoho.search.base.utils.MD5Util;
8 import com.yoho.search.cache.model.CacheObject; 8 import com.yoho.search.cache.model.CacheObject;
@@ -19,116 +19,114 @@ import java.lang.reflect.Type; @@ -19,116 +19,114 @@ import java.lang.reflect.Type;
19 @Service 19 @Service
20 public class SearchCacheService { 20 public class SearchCacheService {
21 21
22 - @Autowired  
23 - private SearchServiceConfiger searchServiceConfiger; 22 + @Autowired
  23 + private SearchServiceConfiger searchServiceConfiger;
24 24
25 - private void addObjectToCache(RedisKeyBuilder redisKeyBuilder, Object object, SearchCache searchCache) {  
26 - // 1、如果不适用缓存,则直接返回  
27 - if (!searchServiceConfiger.useCache()) {  
28 - return;  
29 - }  
30 - // 2、如果缓存不存在,则直接返回  
31 - if (searchCache == null || searchCache.getCache() == null) {  
32 - return;  
33 - }  
34 - // 3、加入缓存  
35 - CacheObject cacheObject = null;  
36 - if (object instanceof JSONObject) {  
37 - cacheObject = new CacheObject((JSONObject) object);  
38 - } else if (object instanceof JSONArray) {  
39 - cacheObject = new CacheObject((JSONArray) object);  
40 - } else {  
41 - cacheObject = new CacheObject(object);  
42 - }  
43 - searchCache.getCache().addOrUpdate(redisKeyBuilder, cacheObject, searchCache.getCacheInMinute());  
44 - } 25 + private void addObjectToCache(RedisKeyBuilder redisKeyBuilder, Object object, SearchCache searchCache) {
  26 + // 1、如果不适用缓存,则直接返回
  27 + if (!searchServiceConfiger.useCache()) {
  28 + return;
  29 + }
  30 + // 2、如果缓存不存在,则直接返回
  31 + if (searchCache == null || searchCache.getCache() == null) {
  32 + return;
  33 + }
  34 + // 3、加入缓存
  35 + CacheObject cacheObject = null;
  36 + if (object instanceof JSONObject) {
  37 + cacheObject = new CacheObject((JSONObject) object);
  38 + } else {
  39 + cacheObject = new CacheObject(object);
  40 + }
  41 + searchCache.getCache().addOrUpdate(redisKeyBuilder, cacheObject, searchCache.getCacheInMinute());
  42 + }
45 43
46 - /**  
47 - * 从缓存中取数据  
48 - *  
49 - * @param redisKeyBuilder  
50 - * @return  
51 - */  
52 - private CacheObject getCacheObjectFromCache(RedisKeyBuilder redisKeyBuilder, SearchCache searchCache) {  
53 - // 1、如果不适用缓存,则直接返回  
54 - if (!searchServiceConfiger.useCache()) {  
55 - return null;  
56 - }  
57 - // 2、如果缓存不存在,则直接返回  
58 - if (searchCache == null || searchCache.getCache() == null) {  
59 - return null;  
60 - }  
61 - // 3、增加缓存访问次数  
62 - searchCache.incTotalCount(); 44 + /**
  45 + * 从缓存中取数据
  46 + *
  47 + * @param redisKeyBuilder
  48 + * @return
  49 + */
  50 + private CacheObject getCacheObjectFromCache(RedisKeyBuilder redisKeyBuilder, SearchCache searchCache) {
  51 + // 1、如果不适用缓存,则直接返回
  52 + if (!searchServiceConfiger.useCache()) {
  53 + return null;
  54 + }
  55 + // 2、如果缓存不存在,则直接返回
  56 + if (searchCache == null || searchCache.getCache() == null) {
  57 + return null;
  58 + }
  59 + // 3、增加缓存访问次数
  60 + searchCache.incTotalCount();
63 61
64 - // 4、从缓存中获取cacheObject  
65 - CacheObject cacheObject = searchCache.getCache().get(redisKeyBuilder); 62 + // 4、从缓存中获取cacheObject
  63 + CacheObject cacheObject = searchCache.getCache().get(redisKeyBuilder);
66 64
67 - // 5、如果从缓存中拿不到数据,则直接返回  
68 - if (cacheObject == null) {  
69 - return null;  
70 - }  
71 - // 6、增加缓存命中次数,并返回缓存对象  
72 - searchCache.incMatchCount();  
73 - return cacheObject;  
74 - } 65 + // 5、如果从缓存中拿不到数据,则直接返回
  66 + if (cacheObject == null) {
  67 + return null;
  68 + }
  69 + // 6、增加缓存命中次数,并返回缓存对象
  70 + searchCache.incMatchCount();
  71 + return cacheObject;
  72 + }
75 73
76 - /*********************************** JSONObject *****************************************/  
77 - public RedisKeyBuilder genSearchParamString(String indexName, SearchParam searchParam) {  
78 - //1、拼装内容  
79 - StringBuilder redisKeyValue = new StringBuilder();  
80 - redisKeyValue.append("indexName:").append(indexName).append(';');  
81 - redisKeyValue.append("searchType:").append(searchParam.getSearchType() == null ? "" : searchParam.getSearchType().name()).append(';');  
82 - SearchSourceBuilder searchSourceBuilder = SearchParamUtils.genSearchSourceBuilderFromSearchParam(searchParam);  
83 - redisKeyValue.append("searchSource:").append(searchSourceBuilder).append(';'); 74 + /*********************************** JSONObject *****************************************/
  75 + public RedisKeyBuilder genSearchParamString(String indexName, SearchParam searchParam) {
  76 + //1、拼装内容
  77 + StringBuilder redisKeyValue = new StringBuilder();
  78 + redisKeyValue.append("indexName:").append(indexName).append(';');
  79 + redisKeyValue.append("searchType:").append(searchParam.getSearchType() == null ? "" : searchParam.getSearchType().name()).append(';');
  80 + SearchSourceBuilder searchSourceBuilder = SearchParamUtils.genSearchSourceBuilderFromSearchParam(searchParam);
  81 + redisKeyValue.append("searchSource:").append(searchSourceBuilder).append(';');
84 82
85 - //2、构建RedisKeyBuilder  
86 - RedisKeyBuilder redisKeyBuilder = RedisKeyBuilder.newInstance();  
87 - redisKeyBuilder.appendFixed("YOHOSEARCH:");  
88 - redisKeyBuilder.appendFixed("DEFAULT1:");  
89 - redisKeyBuilder.appendVar(MD5Util.string2MD5(redisKeyValue.toString()));  
90 - return redisKeyBuilder;  
91 - } 83 + //2、构建RedisKeyBuilder
  84 + RedisKeyBuilder redisKeyBuilder = RedisKeyBuilder.newInstance();
  85 + redisKeyBuilder.appendFixed("YOHOSEARCH:");
  86 + redisKeyBuilder.appendFixed("DEFAULT1:");
  87 + redisKeyBuilder.appendVar(MD5Util.string2MD5(redisKeyValue.toString()));
  88 + return redisKeyBuilder;
  89 + }
92 90
93 - public void addJSONObjectToCache(SearchCache searchCache, String indexName, SearchParam searchParam, JSONObject jsonObject) {  
94 - RedisKeyBuilder key = this.genSearchParamString(indexName, searchParam);  
95 - this.addObjectToCache(key, jsonObject, searchCache);  
96 - } 91 + public void addJSONObjectToCache(SearchCache searchCache, String indexName, SearchParam searchParam, JSONObject jsonObject) {
  92 + RedisKeyBuilder key = this.genSearchParamString(indexName, searchParam);
  93 + this.addObjectToCache(key, jsonObject, searchCache);
  94 + }
97 95
98 - public JSONObject getJSONObjectFromCache(SearchCache searchCache, String indexName, SearchParam searchParam) {  
99 - RedisKeyBuilder key = this.genSearchParamString(indexName, searchParam);  
100 - CacheObject cacheObject = this.getCacheObjectFromCache(key, searchCache);  
101 - if (cacheObject == null) {  
102 - return null;  
103 - }  
104 - return cacheObject.toJSONObject();  
105 - } 96 + public JSONObject getJSONObjectFromCache(SearchCache searchCache, String indexName, SearchParam searchParam) {
  97 + RedisKeyBuilder key = this.genSearchParamString(indexName, searchParam);
  98 + CacheObject cacheObject = this.getCacheObjectFromCache(key, searchCache);
  99 + if (cacheObject == null) {
  100 + return null;
  101 + }
  102 + return cacheObject.toJSONObject();
  103 + }
106 104
107 - /*********************************** object *****************************************/  
108 - public <T> T getSerializableObjectFromCache(SearchCache searchCache, RedisKeyBuilder redisKeyBuilder, Type type, boolean useJsonSerializable) {  
109 - try {  
110 - CacheObject cacheObject = this.getCacheObjectFromCache(redisKeyBuilder, searchCache);  
111 - if (cacheObject == null) {  
112 - return null;  
113 - }  
114 - if (useJsonSerializable) {  
115 - String stringValue = (String)cacheObject.toObject();  
116 - return JSON.parseObject(stringValue, type);  
117 - } else {  
118 - return (T) cacheObject.getValue();  
119 - }  
120 - } catch (Exception e) {  
121 - e.printStackTrace();  
122 - return null;  
123 - }  
124 - } 105 + /*********************************** object *****************************************/
  106 + public <T> T getSerializableObjectFromCache(SearchCache searchCache, RedisKeyBuilder redisKeyBuilder, Type type, boolean useJsonSerializable) {
  107 + try {
  108 + CacheObject cacheObject = this.getCacheObjectFromCache(redisKeyBuilder, searchCache);
  109 + if (cacheObject == null) {
  110 + return null;
  111 + }
  112 + if (useJsonSerializable) {
  113 + String stringValue = (String) cacheObject.toObject();
  114 + return JSON.parseObject(stringValue, type);
  115 + } else {
  116 + return (T) cacheObject.getValue();
  117 + }
  118 + } catch (Exception e) {
  119 + e.printStackTrace();
  120 + return null;
  121 + }
  122 + }
125 123
126 - public <T> void addSerializableObjectToCache(SearchCache searchCache, RedisKeyBuilder redisKeyBuilder, T object, boolean useJsonSerializable) {  
127 - if (useJsonSerializable) {  
128 - String jsonStr = JSON.toJSONString(object);  
129 - this.addObjectToCache(redisKeyBuilder, jsonStr, searchCache);  
130 - } else {  
131 - this.addObjectToCache(redisKeyBuilder, object, searchCache);  
132 - }  
133 - } 124 + public <T> void addSerializableObjectToCache(SearchCache searchCache, RedisKeyBuilder redisKeyBuilder, T object, boolean useJsonSerializable) {
  125 + if (useJsonSerializable) {
  126 + String jsonStr = JSON.toJSONString(object, SerializerFeature.WriteMapNullValue, SerializerFeature.DisableCircularReferenceDetect);
  127 + this.addObjectToCache(redisKeyBuilder, jsonStr, searchCache);
  128 + } else {
  129 + this.addObjectToCache(redisKeyBuilder, object, searchCache);
  130 + }
  131 + }
134 } 132 }
1 -package com.yoho.search.cache.model;  
2 -  
3 -import com.alibaba.fastjson.JSON;  
4 -import com.alibaba.fastjson.JSONArray;  
5 -import com.alibaba.fastjson.JSONObject;  
6 -import com.alibaba.fastjson.serializer.SerializerFeature;  
7 -  
8 -import java.io.Serializable;  
9 -  
10 -/**  
11 - * 暂时只支持JSONObject和jsonArray  
12 - *  
13 - * @author hugufei  
14 - *  
15 - */  
16 -public class CacheObject implements Serializable {  
17 -  
18 - private static final long serialVersionUID = -3949382156604252137L;  
19 -  
20 - private String type;  
21 - private Object value;  
22 -  
23 - public CacheObject() {  
24 - }  
25 -  
26 - public CacheObject(Object object) {  
27 - super();  
28 - this.type = "Object";  
29 - this.value = object;  
30 - }  
31 -  
32 - public CacheObject(JSONObject jsonObject) {  
33 - super();  
34 - this.type = "JSONObject";  
35 - this.value = JSON.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue);  
36 - }  
37 -  
38 - public CacheObject(JSONArray jsonArray) {  
39 - super();  
40 - this.type = "JSONArray";  
41 - this.value = JSON.toJSONString(jsonArray, SerializerFeature.WriteMapNullValue);  
42 - }  
43 -  
44 - public String getType() {  
45 - return type;  
46 - }  
47 -  
48 - public void setType(String type) {  
49 - this.type = type;  
50 - }  
51 -  
52 - public Object getValue() {  
53 - return value;  
54 - }  
55 -  
56 - public void setValue(Object value) {  
57 - this.value = value;  
58 - }  
59 -  
60 - public JSONObject toJSONObject() {  
61 - try {  
62 - if (value == null) {  
63 - return null;  
64 - }  
65 - if ("JSONObject".equals(type)) {  
66 - return JSON.parseObject(value.toString());  
67 - }  
68 - return null;  
69 - } catch (Exception e) {  
70 - e.printStackTrace();  
71 - return null;  
72 - }  
73 - }  
74 -  
75 - public JSONArray toJSONArray() {  
76 - try {  
77 - if (value == null) {  
78 - return null;  
79 - }  
80 - if ("JSONArray".equals(type)) {  
81 - return JSON.parseArray(value.toString());  
82 - }  
83 - return null;  
84 - } catch (Exception e) {  
85 - e.printStackTrace();  
86 - return null;  
87 - }  
88 - }  
89 -  
90 - public Object toObject() {  
91 - try {  
92 - if (value == null) {  
93 - return null;  
94 - }  
95 - if ("Object".equals(type)) {  
96 - return value;  
97 - }  
98 - return null;  
99 - } catch (Exception e) {  
100 - e.printStackTrace();  
101 - return null;  
102 - }  
103 - }  
104 -} 1 +package com.yoho.search.cache.model;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.alibaba.fastjson.serializer.SerializerFeature;
  6 +
  7 +import java.io.Serializable;
  8 +
  9 +/**
  10 + * 暂时只支持JSONObject和jsonArray
  11 + *
  12 + * @author hugufei
  13 + *
  14 + */
  15 +public class CacheObject implements Serializable {
  16 +
  17 + private static final long serialVersionUID = -3949382156604252137L;
  18 +
  19 + private String type;
  20 + private Object value;
  21 +
  22 + public CacheObject() {
  23 + }
  24 +
  25 + public CacheObject(Object object) {
  26 + super();
  27 + this.type = "Object";
  28 + this.value = object;
  29 + }
  30 +
  31 + public CacheObject(JSONObject jsonObject) {
  32 + super();
  33 + this.type = "JSONObject";
  34 + this.value = JSON.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue,SerializerFeature.DisableCircularReferenceDetect);
  35 + }
  36 +
  37 + public String getType() {
  38 + return type;
  39 + }
  40 +
  41 + public void setType(String type) {
  42 + this.type = type;
  43 + }
  44 +
  45 + public Object getValue() {
  46 + return value;
  47 + }
  48 +
  49 + public void setValue(Object value) {
  50 + this.value = value;
  51 + }
  52 +
  53 + public JSONObject toJSONObject() {
  54 + try {
  55 + if (value == null) {
  56 + return null;
  57 + }
  58 + if ("JSONObject".equals(type)) {
  59 + return JSON.parseObject(value.toString());
  60 + }
  61 + return null;
  62 + } catch (Exception e) {
  63 + e.printStackTrace();
  64 + return null;
  65 + }
  66 + }
  67 +
  68 + public Object toObject() {
  69 + try {
  70 + if (value == null) {
  71 + return null;
  72 + }
  73 + if ("Object".equals(type)) {
  74 + return value;
  75 + }
  76 + return null;
  77 + } catch (Exception e) {
  78 + e.printStackTrace();
  79 + return null;
  80 + }
  81 + }
  82 +}
@@ -83,7 +83,7 @@ public class RedisCacheUtils { @@ -83,7 +83,7 @@ public class RedisCacheUtils {
83 * @return 83 * @return
84 */ 84 */
85 private static <T> String serializeToString(T t) { 85 private static <T> String serializeToString(T t) {
86 - return JSON.toJSONString(t, SerializerFeature.WriteMapNullValue); 86 + return JSON.toJSONString(t, SerializerFeature.WriteMapNullValue,SerializerFeature.DisableCircularReferenceDetect);
87 } 87 }
88 88
89 private static <T> T unserializeFromString(String cacheObjectValue, Class<T> clazz) { 89 private static <T> T unserializeFromString(String cacheObjectValue, Class<T> clazz) {
1 package com.yoho.search.restapi.scene; 1 package com.yoho.search.restapi.scene;
2 2
3 -import java.util.Map;  
4 -  
5 -import javax.servlet.http.HttpServletRequest;  
6 -  
7 -import com.yoho.search.service.scene.searchlike.SearchLikeNotInShopService;  
8 -import com.yoho.search.service.scene.searchlike.SearchLikeHelper; 3 +import com.yoho.search.common.utils.HttpServletRequestUtils;
  4 +import com.yoho.search.models.SearchApiResult;
  5 +import com.yoho.search.service.scene.searchlike.*;
9 import org.apache.commons.collections.MapUtils; 6 import org.apache.commons.collections.MapUtils;
10 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.stereotype.Controller; 8 import org.springframework.stereotype.Controller;
@@ -13,89 +10,92 @@ import org.springframework.web.bind.annotation.RequestMapping; @@ -13,89 +10,92 @@ import org.springframework.web.bind.annotation.RequestMapping;
13 import org.springframework.web.bind.annotation.RequestMethod; 10 import org.springframework.web.bind.annotation.RequestMethod;
14 import org.springframework.web.bind.annotation.ResponseBody; 11 import org.springframework.web.bind.annotation.ResponseBody;
15 12
16 -import com.yoho.search.common.utils.HttpServletRequestUtils;  
17 -import com.yoho.search.models.SearchApiResult;  
18 -import com.yoho.search.service.scene.searchlike.SearchLikeInShopService;  
19 -import com.yoho.search.service.scene.searchlike.SearchLikeSceneService;  
20 -import com.yoho.search.service.scene.searchlike.ProductListWithSupplyService;  
21 -import com.yoho.search.service.scene.searchlike.SimilarProductService; 13 +import javax.servlet.http.HttpServletRequest;
  14 +import java.util.Map;
22 15
23 /** 16 /**
24 * 找相似相关功能 17 * 找相似相关功能
25 - * 18 + *
26 * @author hugufei 19 * @author hugufei
27 */ 20 */
28 21
29 @Controller 22 @Controller
30 public class SearchLikeSecneController { 23 public class SearchLikeSecneController {
31 24
32 - @Autowired  
33 - private SearchLikeSceneService searchLikeService;  
34 - @Autowired  
35 - private SearchLikeInShopService searchLikeInShopService;  
36 - @Autowired  
37 - private ProductListWithSupplyService productListWithSupplyService;  
38 - @Autowired  
39 - private SimilarProductService similarProductService;  
40 - @Autowired  
41 - private SearchLikeNotInShopService searchLikeNotInShopService;  
42 - @Autowired  
43 - private SearchLikeHelper searchLikeHelper;  
44 -  
45 - @RequestMapping(method = RequestMethod.GET, value = "/searchLike")  
46 - @ResponseBody  
47 - public SearchApiResult searchLike(HttpServletRequest request) {  
48 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
49 - return searchLikeService.searchLike(paramMap);  
50 - } 25 + @Autowired
  26 + private SearchLikeSceneService searchLikeService;
  27 + @Autowired
  28 + private SearchLikeInShopService searchLikeInShopService;
  29 + @Autowired
  30 + private ProductListWithSupplyService productListWithSupplyService;
  31 + @Autowired
  32 + private SimilarProductService similarProductService;
  33 + @Autowired
  34 + private SearchLikeNotInShopService searchLikeNotInShopService;
  35 + @Autowired
  36 + private SearchLikeHelper searchLikeHelper;
51 37
52 - @RequestMapping(method = RequestMethod.GET, value = "/searchLikeInShop")  
53 - @ResponseBody  
54 - public SearchApiResult searchLikeInShop(HttpServletRequest request) {  
55 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
56 - int viewNum = MapUtils.getIntValue(paramMap,"viewNum",10);  
57 - SearchApiResult result = searchLikeInShopService.searchLikeInShop(paramMap);  
58 - return searchLikeHelper.buildSearchApiResultWithViewNum(result,viewNum);  
59 - } 38 + @RequestMapping(method = RequestMethod.GET, value = "/searchLike")
  39 + @ResponseBody
  40 + public SearchApiResult searchLike(HttpServletRequest request) {
  41 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  42 + return searchLikeService.searchLike(paramMap);
  43 + }
60 44
61 - @RequestMapping(method = RequestMethod.GET, value = "/searchLikeNotInShop")  
62 - @ResponseBody  
63 - public SearchApiResult searchLikeNotInShop(HttpServletRequest request) {  
64 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
65 - int viewNum = MapUtils.getIntValue(paramMap,"viewNum",10);  
66 - SearchApiResult result = searchLikeNotInShopService.searchLikeSimilarSknNotInShop(paramMap);  
67 - return searchLikeHelper.buildSearchApiResultWithViewNum(result,viewNum);  
68 - } 45 + @RequestMapping(method = RequestMethod.GET, value = "/searchLikeInShop")
  46 + @ResponseBody
  47 + public SearchApiResult searchLikeInShop(HttpServletRequest request) {
  48 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  49 + int viewNum = MapUtils.getIntValue(paramMap, "viewNum", 10);
  50 + int uid = MapUtils.getIntValue(paramMap, "uid", 0);
  51 + if (uid>0 && uid % 1024 < 512) {
  52 + paramMap.put("use_yoho_image", "true");
  53 + }
  54 + SearchApiResult result = searchLikeInShopService.searchLikeInShop(paramMap);
  55 + return searchLikeHelper.buildSearchApiResultWithViewNum(result, viewNum);
  56 + }
69 57
  58 + @RequestMapping(method = RequestMethod.GET, value = "/searchLikeNotInShop")
  59 + @ResponseBody
  60 + public SearchApiResult searchLikeNotInShop(HttpServletRequest request) {
  61 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  62 + int viewNum = MapUtils.getIntValue(paramMap, "viewNum", 10);
  63 + int uid = MapUtils.getIntValue(paramMap, "uid", 0);
  64 + if (uid>0 && uid % 1024 < 512) {
  65 + paramMap.put("use_yoho_image", "true");
  66 + }
  67 + SearchApiResult result = searchLikeNotInShopService.searchLikeSimilarSknNotInShop(paramMap);
  68 + return searchLikeHelper.buildSearchApiResultWithViewNum(result, viewNum);
  69 + }
70 70
71 - @RequestMapping(method = RequestMethod.GET, value = "/searchLikeForSaleOut")  
72 - @ResponseBody  
73 - public SearchApiResult searchLikeForSaleOut(HttpServletRequest request) {  
74 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
75 - return searchLikeService.searchLikeForSaleOut(paramMap);  
76 - } 71 + @RequestMapping(method = RequestMethod.GET, value = "/searchLikeForSaleOut")
  72 + @ResponseBody
  73 + public SearchApiResult searchLikeForSaleOut(HttpServletRequest request) {
  74 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  75 + return searchLikeService.searchLikeForSaleOut(paramMap);
  76 + }
77 77
78 - /**  
79 - * 获取商品列表,支持如果传入skn无效,补充相似skn  
80 - */  
81 - @RequestMapping(method = RequestMethod.GET, value = "/productindex/productListWithSupply")  
82 - @ResponseBody  
83 - public SearchApiResult productList(HttpServletRequest request) {  
84 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
85 - return productListWithSupplyService.productListWithSupply(paramMap);  
86 - } 78 + /**
  79 + * 获取商品列表,支持如果传入skn无效,补充相似skn
  80 + */
  81 + @RequestMapping(method = RequestMethod.GET, value = "/productindex/productListWithSupply")
  82 + @ResponseBody
  83 + public SearchApiResult productList(HttpServletRequest request) {
  84 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  85 + return productListWithSupplyService.productListWithSupply(paramMap);
  86 + }
87 87
88 - /**  
89 - * 根据一堆skn找相似的skn  
90 - *  
91 - * @param request  
92 - * @return  
93 - */  
94 - @RequestMapping(method = RequestMethod.GET, value = "/productindex/similarProductList")  
95 - @ResponseBody  
96 - public SearchApiResult similarProductList(HttpServletRequest request) {  
97 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
98 - return similarProductService.similarProductList(paramMap);  
99 - } 88 + /**
  89 + * 根据一堆skn找相似的skn
  90 + *
  91 + * @param request
  92 + * @return
  93 + */
  94 + @RequestMapping(method = RequestMethod.GET, value = "/productindex/similarProductList")
  95 + @ResponseBody
  96 + public SearchApiResult similarProductList(HttpServletRequest request) {
  97 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  98 + return similarProductService.similarProductList(paramMap);
  99 + }
100 100
101 } 101 }
@@ -12,24 +12,24 @@ import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilde @@ -12,24 +12,24 @@ import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilde
12 import java.util.List; 12 import java.util.List;
13 import java.util.Map; 13 import java.util.Map;
14 14
15 -public class ShopBrandAggregation extends AbstractAggregation { 15 +public class BrandShopAggregation extends AbstractAggregation {
16 16
17 private int firstSize; 17 private int firstSize;
18 private int secondSize; 18 private int secondSize;
19 19
20 20
21 - public ShopBrandAggregation(int firstSize, int secondSize) { 21 + public BrandShopAggregation(int firstSize, int secondSize) {
22 this.firstSize = firstSize; 22 this.firstSize = firstSize;
23 this.secondSize = secondSize; 23 this.secondSize = secondSize;
24 } 24 }
25 25
26 @Override 26 @Override
27 public String aggName() { 27 public String aggName() {
28 - return "shopAgg"; 28 + return "brandAgg";
29 } 29 }
30 30
31 public String secondAggName() { 31 public String secondAggName() {
32 - return "brandAgg"; 32 + return "shopAgg";
33 } 33 }
34 34
35 @Override 35 @Override
@@ -39,8 +39,8 @@ public class ShopBrandAggregation extends AbstractAggregation { @@ -39,8 +39,8 @@ public class ShopBrandAggregation extends AbstractAggregation {
39 39
40 @Override 40 @Override
41 public AbstractAggregationBuilder<?> getBuilder() { 41 public AbstractAggregationBuilder<?> getBuilder() {
42 - TermsAggregationBuilder aggBuilder = AggregationBuilders.terms(aggName()).field(ProductIndexEsField.shopId).size(firstSize);  
43 - aggBuilder.subAggregation(AggregationBuilders.terms(secondAggName()).field(ProductIndexEsField.brandId).size(secondSize)); 42 + TermsAggregationBuilder aggBuilder = AggregationBuilders.terms(aggName()).field(ProductIndexEsField.brandId).size(firstSize);
  43 + aggBuilder.subAggregation(AggregationBuilders.terms(secondAggName()).field(ProductIndexEsField.shopId).size(secondSize));
44 return aggBuilder; 44 return aggBuilder;
45 } 45 }
46 46
@@ -13,17 +13,17 @@ import java.util.Iterator; @@ -13,17 +13,17 @@ import java.util.Iterator;
13 import java.util.List; 13 import java.util.List;
14 import java.util.Map; 14 import java.util.Map;
15 15
16 -public class ProductAnalysisShopAggregation extends AbstractAggregation { 16 +public class ProductAnalysisBrandAggregation extends AbstractAggregation {
17 17
18 private int size; 18 private int size;
19 19
20 - public ProductAnalysisShopAggregation(int size) { 20 + public ProductAnalysisBrandAggregation(int size) {
21 this.size = size; 21 this.size = size;
22 } 22 }
23 23
24 @Override 24 @Override
25 public String aggName() { 25 public String aggName() {
26 - return "shopIdAgg"; 26 + return "brandIdAgg";
27 } 27 }
28 28
29 @Override 29 @Override
@@ -33,7 +33,7 @@ public class ProductAnalysisShopAggregation extends AbstractAggregation { @@ -33,7 +33,7 @@ public class ProductAnalysisShopAggregation extends AbstractAggregation {
33 33
34 @Override 34 @Override
35 public AbstractAggregationBuilder<?> getBuilder() { 35 public AbstractAggregationBuilder<?> getBuilder() {
36 - return AggregationBuilders.terms(aggName()).field(ProductIndexEsField.shopId).size(size).order(Terms.Order.aggregation("clickuvcount", false)) 36 + return AggregationBuilders.terms(aggName()).field(ProductIndexEsField.brandId).size(size).order(Terms.Order.aggregation("clickuvcount", false))
37 .subAggregation(AggregationBuilders.sum("clickuvcount").field("clickUvCount")); 37 .subAggregation(AggregationBuilders.sum("clickuvcount").field("clickUvCount"));
38 } 38 }
39 39
@@ -43,15 +43,15 @@ public class ProductAnalysisShopAggregation extends AbstractAggregation { @@ -43,15 +43,15 @@ public class ProductAnalysisShopAggregation extends AbstractAggregation {
43 if (aggregation == null) { 43 if (aggregation == null) {
44 return null; 44 return null;
45 } 45 }
46 - List<Integer> shopIds = new ArrayList<>(); 46 + List<Integer> brandIds = new ArrayList<>();
47 Iterator<? extends MultiBucketsAggregation.Bucket> itSizeAgg = aggregation.getBuckets().iterator(); 47 Iterator<? extends MultiBucketsAggregation.Bucket> itSizeAgg = aggregation.getBuckets().iterator();
48 while (itSizeAgg.hasNext()) { 48 while (itSizeAgg.hasNext()) {
49 MultiBucketsAggregation.Bucket ltSize = itSizeAgg.next(); 49 MultiBucketsAggregation.Bucket ltSize = itSizeAgg.next();
50 - String[] shopIdArray=ltSize.getKeyAsString().split(",");  
51 - for (String shopId : shopIdArray) {  
52 - shopIds.add(Integer.valueOf(shopId)); 50 + String[] brandIdArray=ltSize.getKeyAsString().split(",");
  51 + for (String brandId : brandIdArray) {
  52 + brandIds.add(Integer.valueOf(brandId));
53 } 53 }
54 } 54 }
55 - return shopIds; 55 + return brandIds;
56 } 56 }
57 } 57 }
@@ -20,12 +20,13 @@ import com.yoho.search.models.aggregations.AggKeyCount; @@ -20,12 +20,13 @@ import com.yoho.search.models.aggregations.AggKeyCount;
20 import com.yoho.search.models.aggregations.AggKeyCountTwoLevel; 20 import com.yoho.search.models.aggregations.AggKeyCountTwoLevel;
21 import com.yoho.search.service.aggregations.AggregationsService; 21 import com.yoho.search.service.aggregations.AggregationsService;
22 import com.yoho.search.service.aggregations.impls.ProductAnalysisDateAggregation; 22 import com.yoho.search.service.aggregations.impls.ProductAnalysisDateAggregation;
23 -import com.yoho.search.service.aggregations.impls.ProductAnalysisShopAggregation; 23 +import com.yoho.search.service.aggregations.impls.ProductAnalysisBrandAggregation;
24 import com.yoho.search.service.aggregations.impls.ProductAnalysisSortAggregation; 24 import com.yoho.search.service.aggregations.impls.ProductAnalysisSortAggregation;
25 -import com.yoho.search.service.aggregations.impls.ShopBrandAggregation; 25 +import com.yoho.search.service.aggregations.impls.BrandShopAggregation;
26 import com.yoho.search.service.helper.SearchParamHelper; 26 import com.yoho.search.service.helper.SearchParamHelper;
27 import com.yoho.search.service.recall.beans.persional.UserPersionalFactorComponent; 27 import com.yoho.search.service.recall.beans.persional.UserPersionalFactorComponent;
28 import com.yoho.search.service.recall.beans.vector.BrandVectorCacheBean; 28 import com.yoho.search.service.recall.beans.vector.BrandVectorCacheBean;
  29 +import com.yoho.search.service.recall.config.SpecialShopConstants;
29 import com.yoho.search.service.scene.activity.recommendshop.ActivityShopBrand; 30 import com.yoho.search.service.scene.activity.recommendshop.ActivityShopBrand;
30 import com.yoho.search.service.scene.general.SortGroupService; 31 import com.yoho.search.service.scene.general.SortGroupService;
31 import org.apache.commons.collections.MapUtils; 32 import org.apache.commons.collections.MapUtils;
@@ -182,8 +183,6 @@ public class RecommendOnProductAnalysisService { @@ -182,8 +183,6 @@ public class RecommendOnProductAnalysisService {
182 } 183 }
183 184
184 private List<Integer> getSeenShops(Map<String, String> paramMap) { 185 private List<Integer> getSeenShops(Map<String, String> paramMap) {
185 - Map<String, String> paramMapClone = new HashMap<>();  
186 - paramMapClone.putAll(paramMap);  
187 List<Integer> seenShopIds = new ArrayList<>(); 186 List<Integer> seenShopIds = new ArrayList<>();
188 try { 187 try {
189 int uid = MapUtils.getIntValue(paramMap, "uid", 0); 188 int uid = MapUtils.getIntValue(paramMap, "uid", 0);
@@ -193,9 +192,13 @@ public class RecommendOnProductAnalysisService { @@ -193,9 +192,13 @@ public class RecommendOnProductAnalysisService {
193 if (userFactor != null && !CollectionUtils.isEmpty(userFactor.getRealTimeSortBrandList())) { 192 if (userFactor != null && !CollectionUtils.isEmpty(userFactor.getRealTimeSortBrandList())) {
194 List<Integer> realTimeBrandIds = userFactor.getRealTimeSortBrandList().stream().map(SortBrand::getBrandId).collect(Collectors.toList()); 193 List<Integer> realTimeBrandIds = userFactor.getRealTimeSortBrandList().stream().map(SortBrand::getBrandId).collect(Collectors.toList());
195 if (!CollectionUtils.isEmpty(realTimeBrandIds)) { 194 if (!CollectionUtils.isEmpty(realTimeBrandIds)) {
196 - paramMapClone.put(SearchRequestParams.PARAM_SEARCH_BRAND, StringUtils.join(realTimeBrandIds, ","));  
197 - addDefaultParamsToParamMap(paramMapClone);  
198 - seenShopIds = aggShopId(paramMapClone, 10); 195 + List<AggKeyCountTwoLevel> aggKeyCountTwoLevels = productAggBrandShopIds(paramMap, 10000, 20);
  196 + List<ActivityShopBrand> shopBrands = doCombineShopIdAndBrandId(aggKeyCountTwoLevels, realTimeBrandIds);
  197 + if (CollectionUtils.isEmpty(shopBrands)) {
  198 + return seenShopIds;
  199 + }
  200 + seenShopIds = shopBrands.stream().map(ActivityShopBrand::getShopId).distinct().collect(Collectors.toList());
  201 + return SearchCollectionUtils.safeSubList(seenShopIds, 0, 10);
199 } 202 }
200 } 203 }
201 } 204 }
@@ -205,53 +208,40 @@ public class RecommendOnProductAnalysisService { @@ -205,53 +208,40 @@ public class RecommendOnProductAnalysisService {
205 return seenShopIds; 208 return seenShopIds;
206 } 209 }
207 210
208 -  
209 - private List<Integer> aggShopId(Map<String, String> paramMap, int aggCount) throws Exception{  
210 - List<Integer> seenShopIds = new ArrayList<>();  
211 - JSONObject aggResult = aggregationsService.getShopAggregationResult(paramMap, aggCount);  
212 - if (aggResult != null && !CollectionUtils.isEmpty(aggResult.getJSONArray("shopAgg"))) {  
213 - JSONArray shopList = aggResult.getJSONArray("shopAgg");  
214 - for (Object shop : shopList) {  
215 - seenShopIds.add(((JSONObject)shop).getInteger("shop_id"));  
216 - }  
217 - }  
218 - return seenShopIds;  
219 - }  
220 -  
221 private List<Integer> getRecommendShopWithPersonal(Map<String, String> paramMap, int viewNum, int uid, String udid) throws Exception{ 211 private List<Integer> getRecommendShopWithPersonal(Map<String, String> paramMap, int viewNum, int uid, String udid) throws Exception{
222 List<Integer> recShopIds = new ArrayList<>(); 212 List<Integer> recShopIds = new ArrayList<>();
223 SearchParam searchParam = buildSearchParam(paramMap); 213 SearchParam searchParam = buildSearchParam(paramMap);
224 - List<Integer> aggBestShopIds = aggBestShopIds(searchParam, 1000);  
225 - addDefaultParamsToParamMap(paramMap);  
226 - SearchParam searchParam2 = searchParamHelper.buildDefault(paramMap);  
227 - List<AggKeyCountTwoLevel> aggKeyCountTwoLevels = productAggShopBrandIds(searchParam2, 100000, 200);  
228 - List<ActivityShopBrand> shopBrands = combineShopIdAndBrandId(aggKeyCountTwoLevels, aggBestShopIds, viewNum); 214 + List<Integer> aggBestBrandIds = aggBestBrandIds(searchParam, 1000);
  215 + List<AggKeyCountTwoLevel> aggKeyCountTwoLevels = productAggBrandShopIds(paramMap, 10000, 100);
  216 + List<ActivityShopBrand> shopBrands = combineShopIdAndBrandId(aggKeyCountTwoLevels, aggBestBrandIds, viewNum + 10);
229 if (CollectionUtils.isEmpty(shopBrands)) { 217 if (CollectionUtils.isEmpty(shopBrands)) {
230 return recShopIds; 218 return recShopIds;
231 } 219 }
232 - recShopIds = shopBrands.stream().map(ActivityShopBrand::getShopId).collect(Collectors.toList());  
233 - if (uid > 0 || StringUtils.isNotBlank(udid)) {  
234 - recShopIds = reorderShopOnUserPersonalBrand(shopBrands, aggKeyCountTwoLevels, uid, udid);  
235 - } 220 + recShopIds = reorderShopOnUserPersonalBrand(shopBrands, aggKeyCountTwoLevels, uid, udid);
236 return SearchCollectionUtils.safeSubList(recShopIds, 0, viewNum); 221 return SearchCollectionUtils.safeSubList(recShopIds, 0, viewNum);
237 } 222 }
238 223
239 //从yoho_product_analysis聚合卖的最好的shopId 224 //从yoho_product_analysis聚合卖的最好的shopId
240 - private List<Integer> aggBestShopIds(SearchParam searchParam, int shopSize) throws Exception {  
241 - IAggregation aggregation = new ProductAnalysisShopAggregation(shopSize); 225 + private List<Integer> aggBestBrandIds(SearchParam searchParam, int shopSize) throws Exception {
  226 + IAggregation aggregation = new ProductAnalysisBrandAggregation(shopSize);
242 searchParam.setAggregationBuilders(Arrays.asList(aggregation.getBuilder())); 227 searchParam.setAggregationBuilders(Arrays.asList(aggregation.getBuilder()));
243 JSONObject jsonObject = aggregationsService.getAggNameAndResponseWithCache(aggregation, searchParam, ISearchConstants.INDEX_NAME_YOHO_PRODUCT_ANALYSIS); 228 JSONObject jsonObject = aggregationsService.getAggNameAndResponseWithCache(aggregation, searchParam, ISearchConstants.INDEX_NAME_YOHO_PRODUCT_ANALYSIS);
244 - List<Integer> aggShopIds = new ArrayList<>(); 229 + List<Integer> aggBrandIds = new ArrayList<>();
245 if (jsonObject != null && jsonObject.get(aggregation.aggName()) != null) { 230 if (jsonObject != null && jsonObject.get(aggregation.aggName()) != null) {
246 - aggShopIds = JSON.parseArray(JSON.toJSONString(jsonObject.get(aggregation.aggName())), Integer.class); 231 + aggBrandIds = JSON.parseArray(JSON.toJSONString(jsonObject.get(aggregation.aggName())), Integer.class);
247 } 232 }
248 - return aggShopIds; 233 + return aggBrandIds;
249 } 234 }
250 235
251 236
252 - //从pi聚合所有的的shopId  
253 - private List<AggKeyCountTwoLevel> productAggShopBrandIds(SearchParam searchParam, int shopSize, int brandSize) throws Exception {  
254 - IAggregation aggregation = new ShopBrandAggregation(shopSize, brandSize); 237 + private List<AggKeyCountTwoLevel> productAggBrandShopIds(Map<String, String> paramMap, int brandSize, int shopSize) throws Exception {
  238 + Map<String, String> paramMapDefault = new HashMap<>();
  239 + if (StringUtils.isNotBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_SHELVETIME))) {
  240 + paramMapDefault.put(SearchRequestParams.PARAM_SEARCH_SHELVETIME, paramMap.get(SearchRequestParams.PARAM_SEARCH_SHELVETIME));
  241 + }
  242 + addDefaultParamsToParamMap(paramMapDefault);
  243 + SearchParam searchParam = searchParamHelper.buildDefault(paramMapDefault);
  244 + IAggregation aggregation = new BrandShopAggregation(brandSize, shopSize);
255 searchParam.setAggregationBuilders(Arrays.asList(aggregation.getBuilder())); 245 searchParam.setAggregationBuilders(Arrays.asList(aggregation.getBuilder()));
256 JSONObject jsonObject = aggregationsService.getAggNameAndResponseWithCache(aggregation, searchParam); 246 JSONObject jsonObject = aggregationsService.getAggNameAndResponseWithCache(aggregation, searchParam);
257 List<AggKeyCountTwoLevel> aggKeyCountTwoLevels = new ArrayList<>(); 247 List<AggKeyCountTwoLevel> aggKeyCountTwoLevels = new ArrayList<>();
@@ -263,33 +253,40 @@ public class RecommendOnProductAnalysisService { @@ -263,33 +253,40 @@ public class RecommendOnProductAnalysisService {
263 253
264 254
265 //构造卖的最好的shopidbrandid 255 //构造卖的最好的shopidbrandid
266 - private List<ActivityShopBrand> combineShopIdAndBrandId(List<AggKeyCountTwoLevel> aggKeyCountTwoLevels, List<Integer> bestShopIds, int viewNum){ 256 + private List<ActivityShopBrand> combineShopIdAndBrandId(List<AggKeyCountTwoLevel> aggKeyCountTwoLevels, List<Integer> aggBestBrandIds, int size){
267 if (CollectionUtils.isEmpty(aggKeyCountTwoLevels)) { 257 if (CollectionUtils.isEmpty(aggKeyCountTwoLevels)) {
268 return Collections.emptyList(); 258 return Collections.emptyList();
269 } 259 }
270 - List<AggKeyCountTwoLevel> intersection = getCandidateShopBrands(aggKeyCountTwoLevels, bestShopIds, viewNum);  
271 - List<Integer> realBestShopIds = intersection.stream().map(e -> e.getFirstAggKeyCount().getKey()).collect(Collectors.toList()); 260 + List<AggKeyCountTwoLevel> candidateBrandShops = getCandidateBrandShops(aggKeyCountTwoLevels, aggBestBrandIds, size);
  261 + if (CollectionUtils.isEmpty(candidateBrandShops)) {
  262 + return Collections.emptyList();
  263 + }
  264 + List<Integer> realBestBrandIds = candidateBrandShops.stream().map(e -> e.getFirstAggKeyCount().getKey()).collect(Collectors.toList());
  265 + return doCombineShopIdAndBrandId(candidateBrandShops, realBestBrandIds);
  266 + }
  267 +
  268 + private List<ActivityShopBrand> doCombineShopIdAndBrandId(List<AggKeyCountTwoLevel> candidateBrandShops, List<Integer> realBestBrandIds){
272 List<ActivityShopBrand> shopBrandList = new ArrayList<>(); 269 List<ActivityShopBrand> shopBrandList = new ArrayList<>();
273 - Set<Integer> filterBrandIds = new HashSet<>();  
274 - if (!CollectionUtils.isEmpty(intersection) && !CollectionUtils.isEmpty(realBestShopIds)) {  
275 - Map<Integer, AggKeyCountTwoLevel> intersectionMap = intersection.stream().collect(Collectors.toMap(i -> i.getFirstAggKeyCount().getKey(), p -> p));  
276 - for (Integer shopId : realBestShopIds) {  
277 - if (shopId.equals(0)) { 270 + Set<Integer> filterShopIds = new HashSet<>();
  271 + if (!CollectionUtils.isEmpty(candidateBrandShops) && !CollectionUtils.isEmpty(realBestBrandIds)) {
  272 + Map<Integer, AggKeyCountTwoLevel> andidateBrandShopsMap = candidateBrandShops.stream().collect(Collectors.toMap(i -> i.getFirstAggKeyCount().getKey(), p -> p));
  273 + for (Integer brandId : realBestBrandIds) {
  274 + if (brandId.equals(0)) {
278 continue; 275 continue;
279 } 276 }
280 - AggKeyCountTwoLevel aggKeyCountTwoLevel = intersectionMap.get(shopId); 277 + AggKeyCountTwoLevel aggKeyCountTwoLevel = andidateBrandShopsMap.get(brandId);
281 if (aggKeyCountTwoLevel != null) { 278 if (aggKeyCountTwoLevel != null) {
282 List<AggKeyCount> secondList = aggKeyCountTwoLevel.getSecondAggKeyCountList(); 279 List<AggKeyCount> secondList = aggKeyCountTwoLevel.getSecondAggKeyCountList();
283 - for (AggKeyCount brandAggKeyCount : secondList) {  
284 - Integer brandId = brandAggKeyCount.getKey();  
285 - if (brandId.equals(0)) { 280 + for (AggKeyCount shopAggKeyCount : secondList) {
  281 + Integer shopId = shopAggKeyCount.getKey();
  282 + if (shopId.equals(0)) {
286 continue; 283 continue;
287 } 284 }
288 - if (filterBrandIds.contains(brandId)) { 285 + if (filterShopIds.contains(shopId)) {
289 continue; 286 continue;
290 } 287 }
291 shopBrandList.add(new ActivityShopBrand(shopId, brandId));//取商品数最多的一个店铺即可,防止多品店的问题 288 shopBrandList.add(new ActivityShopBrand(shopId, brandId));//取商品数最多的一个店铺即可,防止多品店的问题
292 - filterBrandIds.add(brandId);//每个品牌只赋给一个店铺 289 + filterShopIds.add(shopId);//每个品牌只赋给一个店铺
293 break; 290 break;
294 } 291 }
295 } 292 }
@@ -298,18 +295,18 @@ public class RecommendOnProductAnalysisService { @@ -298,18 +295,18 @@ public class RecommendOnProductAnalysisService {
298 return shopBrandList; 295 return shopBrandList;
299 } 296 }
300 297
301 - private List<AggKeyCountTwoLevel> getCandidateShopBrands(List<AggKeyCountTwoLevel> aggKeyCountTwoLevels, List<Integer> bestShopIds, int viewNum) { 298 +
  299 + private List<AggKeyCountTwoLevel> getCandidateBrandShops(List<AggKeyCountTwoLevel> aggKeyCountTwoLevels, List<Integer> aggBestBrandIds, int candidateNum) {
302 List<AggKeyCountTwoLevel> candidates = new ArrayList<>(); 300 List<AggKeyCountTwoLevel> candidates = new ArrayList<>();
303 - int candidateNum = 1000;  
304 - if (CollectionUtils.isEmpty(bestShopIds)) { 301 + if (CollectionUtils.isEmpty(aggBestBrandIds)) {
305 candidates = SearchCollectionUtils.safeSubList(aggKeyCountTwoLevels, 0, candidateNum); 302 candidates = SearchCollectionUtils.safeSubList(aggKeyCountTwoLevels, 0, candidateNum);
306 }else { 303 }else {
307 - List<AggKeyCountTwoLevel> filtered = aggKeyCountTwoLevels.stream().filter(e -> bestShopIds.contains(e.getFirstAggKeyCount().getKey())).collect(Collectors.toList()); 304 + List<AggKeyCountTwoLevel> filtered = aggKeyCountTwoLevels.stream().filter(e -> aggBestBrandIds.contains(e.getFirstAggKeyCount().getKey())).collect(Collectors.toList());
308 if (!CollectionUtils.isEmpty(filtered)) { 305 if (!CollectionUtils.isEmpty(filtered)) {
309 Map<Integer, AggKeyCountTwoLevel> filteredMap = filtered.stream().collect(Collectors.toMap(i -> i.getFirstAggKeyCount().getKey(), p -> p)); 306 Map<Integer, AggKeyCountTwoLevel> filteredMap = filtered.stream().collect(Collectors.toMap(i -> i.getFirstAggKeyCount().getKey(), p -> p));
310 - for (Integer shopId : bestShopIds) {  
311 - if (filteredMap.get(shopId) != null) {  
312 - candidates.add(filteredMap.get(shopId)); 307 + for (Integer brandId : aggBestBrandIds) {
  308 + if (filteredMap.get(brandId) != null) {
  309 + candidates.add(filteredMap.get(brandId));
313 } 310 }
314 } 311 }
315 } 312 }
@@ -326,23 +323,24 @@ public class RecommendOnProductAnalysisService { @@ -326,23 +323,24 @@ public class RecommendOnProductAnalysisService {
326 323
327 //获取用户有行为的品类 排序sort, RealTimeSort加分放前面,预测的放后面 324 //获取用户有行为的品类 排序sort, RealTimeSort加分放前面,预测的放后面
328 private List<Integer> reorderShopOnUserPersonalBrand(List<ActivityShopBrand> shopBrands, List<AggKeyCountTwoLevel> aggKeyCountTwoLevels, int uid, String udid) { 325 private List<Integer> reorderShopOnUserPersonalBrand(List<ActivityShopBrand> shopBrands, List<AggKeyCountTwoLevel> aggKeyCountTwoLevels, int uid, String udid) {
329 - List<Integer> aggBestShopIds = shopBrands.stream().map(ActivityShopBrand::getShopId).collect(Collectors.toList());  
330 - UserPersonalFactorRspNew userFactor = getUserPersonalFactor(uid, udid);  
331 - if (userFactor != null && !CollectionUtils.isEmpty(userFactor.getRealTimeSortBrandList())) {  
332 - if (!CollectionUtils.isEmpty(userFactor.getBrandVectorW2v())) {  
333 - calScore(shopBrands, userFactor.getBrandVectorW2v(), false);  
334 - } else {  
335 - calScore(shopBrands, userFactor.getBrandVector(), true); 326 + if (uid > 0 || StringUtils.isNotBlank(udid)) {
  327 + UserPersonalFactorRspNew userFactor = getUserPersonalFactor(uid, udid);
  328 + if (userFactor != null && !CollectionUtils.isEmpty(userFactor.getRealTimeSortBrandList())) {
  329 + if (!CollectionUtils.isEmpty(userFactor.getBrandVectorW2v())) {
  330 + calScore(shopBrands, userFactor.getBrandVectorW2v(), false);
  331 + } else {
  332 + calScore(shopBrands, userFactor.getBrandVector(), true);
  333 + }
  334 + Collections.sort(shopBrands, (o1, o2) -> (o2.getScore()).compareTo(o1.getScore()));
  335 + List<Integer> orderedAggBestShopIds = shopBrands.stream().map(ActivityShopBrand::getShopId).collect(Collectors.toList());
  336 + List<Integer> personalBrandIds = userFactor.getRealTimeSortBrandList().stream().map(SortBrand::getBrandId).collect(Collectors.toList());
  337 + List<ActivityShopBrand> personalShopBrands = doCombineShopIdAndBrandId(aggKeyCountTwoLevels, personalBrandIds);
  338 + List<Integer> personalShopIds = personalShopBrands.stream().map(ActivityShopBrand::getShopId).collect(Collectors.toList());
  339 + personalShopIds.addAll(orderedAggBestShopIds);
  340 + return personalShopIds.stream().distinct().collect(Collectors.toList());
336 } 341 }
337 - Collections.sort(shopBrands, (o1, o2) -> (o2.getScore()).compareTo(o1.getScore()));  
338 - List<Integer> orderedAggBestShopIds = shopBrands.stream().map(ActivityShopBrand::getShopId).collect(Collectors.toList());  
339 - List<Integer> personalBrandIds = userFactor.getRealTimeSortBrandList().stream().map(SortBrand::getBrandId).collect(Collectors.toList());  
340 - Map<Integer, Integer> brandId2ShopIdMap = shopBrands.stream().collect(Collectors.toMap(ActivityShopBrand::getBrandId, ActivityShopBrand::getShopId));  
341 - List<Integer> personalShopIds = personalBrandIds.stream().filter(e -> brandId2ShopIdMap.get(e) != null).map(e -> brandId2ShopIdMap.get(e)).distinct().collect(Collectors.toList());  
342 - personalShopIds.addAll(orderedAggBestShopIds);  
343 - return personalShopIds.stream().distinct().collect(Collectors.toList());  
344 } 342 }
345 - return aggBestShopIds; 343 + return shopBrands.stream().map(ActivityShopBrand::getShopId).distinct().collect(Collectors.toList());
346 } 344 }
347 345
348 /** 346 /**
@@ -443,10 +441,15 @@ public class RecommendOnProductAnalysisService { @@ -443,10 +441,15 @@ public class RecommendOnProductAnalysisService {
443 441
444 //SearchParam 442 //SearchParam
445 private SearchParam buildSearchParam(Map<String, String> paramMap) { 443 private SearchParam buildSearchParam(Map<String, String> paramMap) {
  444 + paramMap.put(SearchRequestParams.PARAM_SEARCH_NOT_SHOP_ID, SpecialShopConstants.JISHOU_SHOP_ID.toString());// 非寄售店铺
446 QueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); 445 QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
447 BoolQueryBuilder boolFilter = QueryBuilders.boolQuery(); 446 BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
448 addMustIntTermsQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_GENDER, ProductIndexEsField.gender); 447 addMustIntTermsQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_GENDER, ProductIndexEsField.gender);
449 addMustIntTermsQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_YH_CHANNEL, "yhChannel"); 448 addMustIntTermsQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_YH_CHANNEL, "yhChannel");
  449 + addMustIntTermsQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_MAXSORT, ProductIndexEsField.maxSortId);
  450 + addMustIntTermsQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_MIDDLESORT, ProductIndexEsField.middleSortId);
  451 + addMustIntTermsQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_SMALLSORT, ProductIndexEsField.smallSortId);
  452 + addMustNotIntTermsQuery(boolFilter,paramMap, SearchRequestParams.PARAM_SEARCH_NOT_SHOP_ID,ProductIndexEsField.shopId);
450 addMustDoubleRangeQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_SHELVETIME, ProductIndexEsField.shelveTime); 453 addMustDoubleRangeQuery(boolFilter, paramMap, SearchRequestParams.PARAM_SEARCH_SHELVETIME, ProductIndexEsField.shelveTime);
451 try { 454 try {
452 List<String> day_date = dateRange.get("DAY_DATE"); 455 List<String> day_date = dateRange.get("DAY_DATE");
@@ -475,6 +478,15 @@ public class RecommendOnProductAnalysisService { @@ -475,6 +478,15 @@ public class RecommendOnProductAnalysisService {
475 boolFilter.must(QueryBuilders.termsQuery(esField, values)); 478 boolFilter.must(QueryBuilders.termsQuery(esField, values));
476 } 479 }
477 480
  481 + private void addMustNotIntTermsQuery(BoolQueryBuilder boolFilter,Map<String, String> paramMap, String paramName, String esField){
  482 + List<Integer> values = ConvertUtils.stringToIntList(paramMap.get(paramName), ",");
  483 + if(values==null || values.isEmpty()){
  484 + return;
  485 + }
  486 + boolFilter.mustNot(QueryBuilders.termsQuery(esField, values));
  487 + }
  488 +
  489 +
478 private void addMustDoubleRangeQuery(BoolQueryBuilder boolFilter, Map<String, String> paramMap, String paramName, String esField) { 490 private void addMustDoubleRangeQuery(BoolQueryBuilder boolFilter, Map<String, String> paramMap, String paramName, String esField) {
479 List<Double> values = ConvertUtils.stringToDoubleList(paramMap.get(paramName), ","); 491 List<Double> values = ConvertUtils.stringToDoubleList(paramMap.get(paramName), ",");
480 if (values == null || values.isEmpty() || values.size() != 2) { 492 if (values == null || values.isEmpty() || values.size() != 2) {
@@ -490,6 +502,7 @@ public class RecommendOnProductAnalysisService { @@ -490,6 +502,7 @@ public class RecommendOnProductAnalysisService {
490 paramMap.put(SearchRequestParams.PARAM_SEARCH_SHOWSOLDOUT, "1");// 显示延期显示的商品 502 paramMap.put(SearchRequestParams.PARAM_SEARCH_SHOWSOLDOUT, "1");// 显示延期显示的商品
491 paramMap.put(SearchRequestParams.PARAM_SEARCH_ISOUTLETS, "2");// 非奥莱 503 paramMap.put(SearchRequestParams.PARAM_SEARCH_ISOUTLETS, "2");// 非奥莱
492 paramMap.put(SearchRequestParams.PARAM_SEARCH_ATTRIBUTE_NOT, "2");// 非赠品 504 paramMap.put(SearchRequestParams.PARAM_SEARCH_ATTRIBUTE_NOT, "2");// 非赠品
  505 + paramMap.put(SearchRequestParams.PARAM_SEARCH_NOT_SHOP_ID, SpecialShopConstants.JISHOU_SHOP_ID.toString());// 非寄售店铺
493 } 506 }
494 507
495 private void addShelveTime(Map<String, String> paramMap) { 508 private void addShelveTime(Map<String, String> paramMap) {
1 package com.yoho.search.service.scene.searchlike; 1 package com.yoho.search.service.scene.searchlike;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
4 -import com.yoho.search.base.utils.SearchCollectionUtils;  
5 -import com.yoho.search.base.utils.ProductIndexEsField;  
6 import com.yoho.search.aop.cache.SearchCacheAble; 4 import com.yoho.search.aop.cache.SearchCacheAble;
  5 +import com.yoho.search.base.utils.ProductIndexEsField;
  6 +import com.yoho.search.base.utils.SearchCollectionUtils;
  7 +import com.yoho.search.bo.BigdataSimilarSknIndexBO;
7 import com.yoho.search.common.SearchRequestParams; 8 import com.yoho.search.common.SearchRequestParams;
8 import com.yoho.search.core.es.model.SearchParam; 9 import com.yoho.search.core.es.model.SearchParam;
9 import com.yoho.search.models.SearchApiResult; 10 import com.yoho.search.models.SearchApiResult;
10 -  
11 import com.yoho.search.service.helper.ProductListHelper; 11 import com.yoho.search.service.helper.ProductListHelper;
  12 +import com.yoho.search.service.index.BigdataSimilarSknIndexBaseService;
12 import com.yoho.search.service.index.ProductIndexBaseService; 13 import com.yoho.search.service.index.ProductIndexBaseService;
  14 +import org.apache.commons.collections.CollectionUtils;
  15 +import org.apache.commons.collections.MapUtils;
13 import org.apache.commons.lang.StringUtils; 16 import org.apache.commons.lang.StringUtils;
14 import org.elasticsearch.index.query.BoolQueryBuilder; 17 import org.elasticsearch.index.query.BoolQueryBuilder;
15 import org.elasticsearch.index.query.QueryBuilder; 18 import org.elasticsearch.index.query.QueryBuilder;
@@ -29,113 +32,182 @@ import java.util.Map; @@ -29,113 +32,182 @@ import java.util.Map;
29 32
30 /** 33 /**
31 * 店铺内找相似 34 * 店铺内找相似
32 - * 35 + *
33 * @author gufei.hu 36 * @author gufei.hu
34 */ 37 */
35 @Service 38 @Service
36 public class SearchLikeInShopService { 39 public class SearchLikeInShopService {
37 40
38 - private static final Logger logger = LoggerFactory.getLogger(SearchLikeInShopService.class);  
39 -  
40 - @Autowired  
41 - private SearchLikeHelper searchLikeHelper;  
42 - @Autowired  
43 - private ProductIndexBaseService productIndexBaseService;  
44 - @Autowired  
45 - private ProductListHelper productListHelper;  
46 -  
47 - /**  
48 - * 店铺内推荐  
49 - *  
50 - * @param paramMap  
51 - * @return  
52 - */  
53 - @SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_IN_SHOP_NEW", includeParams = { "product_skn"})  
54 - public SearchApiResult searchLikeInShop(Map<String, String> paramMap) {  
55 - try {  
56 - // 1、获取参数  
57 - String productSkn = paramMap.get(SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN);  
58 - if (StringUtils.isBlank(productSkn)) {  
59 - return new SearchApiResult().setCode(400).setMessage("请输入SKN");  
60 - }  
61 - // 2、检测分页参数【默认30条】  
62 - int viewNum = 30;  
63 - // 3、获取当前查询的SKN的基本信息  
64 - JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn);  
65 - if (productInfoInEs == null) {  
66 - return new SearchApiResult().setCode(400).setMessage("SKN不存在");  
67 - }  
68 - // 4、设置SearchParams  
69 - List<SearchParam> searchParams = new ArrayList<SearchParam>();  
70 - searchParams.add(this.builderSearchParam(productInfoInEs, Arrays.asList(productSkn), viewNum));  
71 - // 5、获取搜索结果[截取条数]  
72 - List<Map<String, Object>> tempProductList = searchLikeHelper.queryProductList(searchParams);  
73 - if (tempProductList.size() > viewNum) {  
74 - tempProductList = SearchCollectionUtils.safeSubList(tempProductList,0, viewNum);  
75 - }  
76 - //6、保留偶数  
77 - if (tempProductList.size() % 2 > 0) {  
78 - tempProductList = SearchCollectionUtils.safeSubList(tempProductList, 0, tempProductList.size() - 1);  
79 - }  
80 - // 7、构造返回结果  
81 - List<Map<String, Object>> productListResults = new ArrayList<Map<String, Object>>();  
82 - if (!tempProductList.isEmpty()) {  
83 - productListResults = productListHelper.buildReturnInfoByEsSourceList(tempProductList);  
84 - }  
85 - JSONObject result = new JSONObject();  
86 - result.put("product_info", searchLikeHelper.genProductInfoResult(productInfoInEs));  
87 - result.put("product_list", productListResults);  
88 - return new SearchApiResult().setData(result);  
89 - } catch (Exception e) {  
90 - logger.error(e.getMessage(), e);  
91 - return new SearchApiResult().setData(null).setMessage("searchLikeInShop Exception").setCode(500);  
92 - }  
93 - }  
94 -  
95 - private SearchParam builderSearchParam(JSONObject productInfoInEs, List<String> productSkns, int pageSize) {  
96 - // 1、设置SearchParam  
97 - SearchParam searchParam = new SearchParam();  
98 - // 2)设置query和filter  
99 - searchParam.setQuery(this.buildCharsetQueryBuilder(productInfoInEs, "20%"));  
100 - searchParam.setFiter(this.builderFilterBuilder(productInfoInEs, productSkns));  
101 - // 3、设置排序规则[按打分排序]  
102 - List<SortBuilder<?>> sortBuilders = new ArrayList<SortBuilder<?>>();  
103 - sortBuilders.add(SortBuilders.scoreSort().order(SortOrder.DESC));  
104 - searchParam.setSortBuilders(sortBuilders);  
105 - // 4、设置分页参数  
106 - searchParam.setOffset(0);  
107 - searchParam.setSize(pageSize);  
108 - // 5)设置返回的参数【节省带宽】  
109 - List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();  
110 - searchParam.setIncludeFields(includeFields);  
111 - return searchParam;  
112 - }  
113 -  
114 - private QueryBuilder builderFilterBuilder(JSONObject productInfoInEs, List<String> notProductSkns) {  
115 - String isGlobalInEs = productInfoInEs.getString(ProductIndexEsField.isGlobal);  
116 - boolean isGlobal = "Y".equalsIgnoreCase(isGlobalInEs);  
117 - BoolQueryBuilder boolFilter = searchLikeHelper.genDefaultSearchLikeFilter(notProductSkns, isGlobal);  
118 - // 1)设置此SKN相关的性别过滤条件  
119 - String gender = productInfoInEs.getString(ProductIndexEsField.gender);  
120 - List<String> genderList = searchLikeHelper.getGenderInfo(gender);  
121 - if (genderList != null && !genderList.isEmpty()) {  
122 - boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.gender, genderList));  
123 - }  
124 - // 2)设置品牌或店铺信息  
125 - Integer brandId = productInfoInEs.getInteger(ProductIndexEsField.brandId);  
126 - Integer shopId = productInfoInEs.getInteger(ProductIndexEsField.shopId);  
127 - if (searchLikeHelper.isLegalInteger(shopId)) {  
128 - boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.shopId, shopId));  
129 - } else if (searchLikeHelper.isLegalInteger(brandId)) {  
130 - boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.brandId, brandId));  
131 - }  
132 - return boolFilter;  
133 - }  
134 -  
135 - private QueryBuilder buildCharsetQueryBuilder(JSONObject productInfoInEs, String minimumShouldMatch) {  
136 - String queryString = searchLikeHelper.genYohoQueryStringWithBrandName(productInfoInEs);  
137 - QueryBuilder queryBuilder = searchLikeHelper.buildCharsetQueryBuilder(queryString, minimumShouldMatch);  
138 - return queryBuilder;  
139 - } 41 + private static final Logger logger = LoggerFactory.getLogger(SearchLikeInShopService.class);
  42 +
  43 + @Autowired
  44 + private SearchLikeHelper searchLikeHelper;
  45 + @Autowired
  46 + private ProductIndexBaseService productIndexBaseService;
  47 + @Autowired
  48 + private ProductListHelper productListHelper;
  49 + @Autowired
  50 + private BigdataSimilarSknIndexBaseService bigdataSimilarSknIndexBaseService;
  51 +
  52 + /**
  53 + * 店铺内推荐
  54 + *
  55 + * @param paramMap
  56 + * @return
  57 + */
  58 + @SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_IN_SHOP_NEW", includeParams = {"product_skn", "use_yoho_image"})
  59 + public SearchApiResult searchLikeInShop(Map<String, String> paramMap) {
  60 + try {
  61 + // 1、获取参数
  62 + String productSkn = paramMap.get(SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN);
  63 + if (StringUtils.isBlank(productSkn)) {
  64 + return new SearchApiResult().setCode(400).setMessage("请输入SKN");
  65 + }
  66 + // 2、检测分页参数【默认30条】
  67 + int viewNum = 30;
  68 + // 3、获取当前查询的SKN的基本信息
  69 + JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn);
  70 + if (productInfoInEs == null) {
  71 + return new SearchApiResult().setCode(400).setMessage("SKN不存在");
  72 + }
  73 +
  74 + //4、获取similarskn
  75 + BigdataSimilarSknIndexBO bigdataSimilarSkn = bigdataSimilarSknIndexBaseService.querySimilarSkn(productSkn);
  76 + boolean use_yoho_image = MapUtils.getBooleanValue(paramMap, "use_yoho_image", false);
  77 +
  78 + // 5、设置SearchParams
  79 + List<SearchParam> searchParams = new ArrayList<SearchParam>();
  80 +
  81 + //5.1)图片[同性别+同店铺]
  82 + List<String> sameShopImgSimilarSknsYoho = new ArrayList<>();
  83 + if (use_yoho_image && bigdataSimilarSkn != null && StringUtils.isNotEmpty(bigdataSimilarSkn.getSameShopImgSimilarSknsYoho())) {
  84 + sameShopImgSimilarSknsYoho = searchLikeHelper.getDistinctSknList(bigdataSimilarSkn.getSameShopImgSimilarSknsYoho());
  85 + }
  86 + searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, sameShopImgSimilarSknsYoho));
  87 +
  88 + //5.2)文字相似
  89 + searchParams.add(this.buildCharactersSearchParam(productInfoInEs, viewNum));
  90 +
  91 + // 6、获取搜索结果
  92 + List<List<Map<String, Object>>> queryResults = searchLikeHelper.queryProductLists(searchParams);
  93 + // 7、处理图片和文字的顺序
  94 + List<Map<String, Object>> sameShopImgSimilarProducts = searchLikeHelper.sortProductList(queryResults.get(0), sameShopImgSimilarSknsYoho, viewNum / 2);
  95 + List<Map<String, Object>> charsetSimilarProducts = queryResults.get(1);
  96 +
  97 + // 8、获取临时结果
  98 + List<Map<String, Object>> tempProductList = new ArrayList<>();
  99 + tempProductList.addAll(sameShopImgSimilarProducts);
  100 + tempProductList.addAll(charsetSimilarProducts);
  101 + if (tempProductList.size() > viewNum) {
  102 + tempProductList = SearchCollectionUtils.safeSubList(tempProductList, 0, viewNum);
  103 + }
  104 + // 8.1 保留偶数
  105 + if (tempProductList.size() % 2 > 0) {
  106 + tempProductList = SearchCollectionUtils.safeSubList(tempProductList, 0, tempProductList.size() - 1);
  107 + }
  108 + // 9、构造真实返回结果
  109 + List<Map<String, Object>> productListResults = new ArrayList<>();
  110 + if (!tempProductList.isEmpty()) {
  111 + productListResults = productListHelper.buildReturnInfoByEsSourceList(tempProductList);
  112 + }
  113 + JSONObject result = new JSONObject();
  114 + result.put("product_info", searchLikeHelper.genProductInfoResult(productInfoInEs));
  115 + result.put("product_list", productListResults);
  116 + return new SearchApiResult().setData(result);
  117 + } catch (Exception e) {
  118 + logger.error(e.getMessage(), e);
  119 + return new SearchApiResult().setData(null).setMessage("searchLikeInShop Exception").setCode(500);
  120 + }
  121 + }
  122 +
  123 + /**
  124 + * 构建SimilarSknSearchParam[考虑productSkns为空的情况]
  125 + *
  126 + * @param productInfoInEs
  127 + * @param productSkns
  128 + * @return
  129 + */
  130 + private SearchParam builderSimilarSknSearchParam(JSONObject productInfoInEs, List<String> productSkns) {
  131 + // 1、设置SearchParam
  132 + SearchParam searchParam = new SearchParam();
  133 + // 2)设置query和filter
  134 + searchParam.setFiter(this.builderSearchLikeInShopFilter(productInfoInEs, productSkns, true));
  135 + // 3、设置分页参数
  136 + searchParam.setOffset(0);
  137 + searchParam.setSize(productSkns.size());
  138 + // 4)设置返回的参数【节省带宽】
  139 + List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();
  140 + searchParam.setIncludeFields(includeFields);
  141 + return searchParam;
  142 + }
  143 +
  144 + /**
  145 + * 店铺内按文字找相似
  146 + *
  147 + * @param productInfoInEs
  148 + * @param pageSize
  149 + * @return
  150 + */
  151 + public SearchParam buildCharactersSearchParam(JSONObject productInfoInEs, int pageSize) {
  152 + // 1、设置SearchParam
  153 + SearchParam searchParam = new SearchParam();
  154 + // 2)设置query和filter
  155 + searchParam.setQuery(this.buildeCharactersQueryBuilder(productInfoInEs, "20%"));
  156 + searchParam.setFiter(this.builderSearchLikeInShopFilter(productInfoInEs, null, false));
  157 + // 3、设置排序规则[按打分排序]
  158 + List<SortBuilder<?>> sortBuilders = new ArrayList<>();
  159 + sortBuilders.add(SortBuilders.scoreSort().order(SortOrder.DESC));
  160 + searchParam.setSortBuilders(sortBuilders);
  161 + // 4、设置分页参数
  162 + searchParam.setOffset(0);
  163 + searchParam.setSize(pageSize);
  164 + // 5)设置返回的参数【节省带宽】
  165 + List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();
  166 + searchParam.setIncludeFields(includeFields);
  167 + return searchParam;
  168 + }
  169 +
  170 + private QueryBuilder buildeCharactersQueryBuilder(JSONObject productInfoInEs, String minimumShouldMatch) {
  171 + String queryString = searchLikeHelper.genYohoQueryStringWithBrandName(productInfoInEs);
  172 + QueryBuilder queryBuilder = searchLikeHelper.buildCharsetQueryBuilder(queryString, minimumShouldMatch);
  173 + return queryBuilder;
  174 + }
  175 +
  176 + private BoolQueryBuilder builderSearchLikeInShopFilter(JSONObject productInfoInEs, List<String> inProductSkns, boolean needSameSort) {
  177 + //1) 默认参数
  178 + String productSkn = productInfoInEs.getString(ProductIndexEsField.productSkn);
  179 + String isGlobalInEs = productInfoInEs.getString(ProductIndexEsField.isGlobal);
  180 + boolean isGlobal = "Y".equalsIgnoreCase(isGlobalInEs);
  181 + BoolQueryBuilder boolFilter = searchLikeHelper.genDefaultSearchLikeFilter(Arrays.asList(productSkn), isGlobal);
  182 +
  183 + // 2)设置此SKN相关的性别过滤条件
  184 + String gender = productInfoInEs.getString(ProductIndexEsField.gender);
  185 + List<String> genderList = searchLikeHelper.getGenderInfo(gender);
  186 + if (genderList != null && !genderList.isEmpty()) {
  187 + boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.gender, genderList));
  188 + }
  189 +
  190 + // 3)设置品牌或店铺信息
  191 + Integer brandId = productInfoInEs.getInteger(ProductIndexEsField.brandId);
  192 + Integer shopId = productInfoInEs.getInteger(ProductIndexEsField.shopId);
  193 + if (searchLikeHelper.isLegalInteger(shopId)) {
  194 + boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.shopId, shopId));
  195 + } else if (searchLikeHelper.isLegalInteger(brandId)) {
  196 + boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.brandId, brandId));
  197 + }
  198 +
  199 + // 4)设置productskn
  200 + if (CollectionUtils.isNotEmpty(inProductSkns)) {
  201 + boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, inProductSkns));
  202 + }
  203 +
  204 + // 5)同品类
  205 + Integer middleSortId = productInfoInEs.getInteger(ProductIndexEsField.middleSortId);
  206 + if (needSameSort && searchLikeHelper.isLegalInteger(middleSortId)) {
  207 + boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.middleSortId, middleSortId));
  208 + }
  209 +
  210 + return boolFilter;
  211 + }
140 212
141 } 213 }
@@ -11,6 +11,8 @@ import com.yoho.search.models.SearchApiResult; @@ -11,6 +11,8 @@ import com.yoho.search.models.SearchApiResult;
11 import com.yoho.search.service.helper.ProductListHelper; 11 import com.yoho.search.service.helper.ProductListHelper;
12 import com.yoho.search.service.index.BigdataSimilarSknIndexBaseService; 12 import com.yoho.search.service.index.BigdataSimilarSknIndexBaseService;
13 import com.yoho.search.service.index.ProductIndexBaseService; 13 import com.yoho.search.service.index.ProductIndexBaseService;
  14 +import org.apache.commons.collections.CollectionUtils;
  15 +import org.apache.commons.collections.MapUtils;
14 import org.apache.commons.lang.StringUtils; 16 import org.apache.commons.lang.StringUtils;
15 import org.elasticsearch.index.query.BoolQueryBuilder; 17 import org.elasticsearch.index.query.BoolQueryBuilder;
16 import org.elasticsearch.index.query.QueryBuilder; 18 import org.elasticsearch.index.query.QueryBuilder;
@@ -42,7 +44,7 @@ public class SearchLikeNotInShopService { @@ -42,7 +44,7 @@ public class SearchLikeNotInShopService {
42 @Autowired 44 @Autowired
43 private BigdataSimilarSknIndexBaseService bigdataSimilarSknIndexBaseService; 45 private BigdataSimilarSknIndexBaseService bigdataSimilarSknIndexBaseService;
44 46
45 - @SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_NOT_IN_SHOP_SIMILAR_NEW", includeParams = {"product_skn"}) 47 + @SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_NOT_IN_SHOP_SIMILAR_NEW", includeParams = {"product_skn", "use_yoho_image"})
46 public SearchApiResult searchLikeSimilarSknNotInShop(Map<String, String> paramMap) { 48 public SearchApiResult searchLikeSimilarSknNotInShop(Map<String, String> paramMap) {
47 try { 49 try {
48 // 1、获取参数 50 // 1、获取参数
@@ -51,31 +53,34 @@ public class SearchLikeNotInShopService { @@ -51,31 +53,34 @@ public class SearchLikeNotInShopService {
51 return new SearchApiResult().setCode(400).setMessage("请输入SKN"); 53 return new SearchApiResult().setCode(400).setMessage("请输入SKN");
52 } 54 }
53 // 2、检测分页参数【默认30条,最多60条】 55 // 2、检测分页参数【默认30条,最多60条】
54 - int pageSize = 30; 56 + int viewNum = 30;
55 // 3、获取当前查询的SKN的基本信息 57 // 3、获取当前查询的SKN的基本信息
56 JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn); 58 JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn);
57 if (productInfoInEs == null) { 59 if (productInfoInEs == null) {
58 return new SearchApiResult().setCode(400).setMessage("SKN不存在"); 60 return new SearchApiResult().setCode(400).setMessage("SKN不存在");
59 } 61 }
  62 +
60 //4、获取similarskn 63 //4、获取similarskn
61 BigdataSimilarSknIndexBO bigdataSimilarSkn = bigdataSimilarSknIndexBaseService.querySimilarSkn(productSkn); 64 BigdataSimilarSknIndexBO bigdataSimilarSkn = bigdataSimilarSknIndexBaseService.querySimilarSkn(productSkn);
  65 + boolean use_yoho_image = MapUtils.getBooleanValue(paramMap, "use_yoho_image", false);
62 66
63 //5、构造searchParams 67 //5、构造searchParams
64 List<SearchParam> searchParams = new ArrayList<>(); 68 List<SearchParam> searchParams = new ArrayList<>();
65 - //5.1)图片[性别+不同店铺+同品类] 69 +
  70 + //5.1)有货图片相似[性别+不同店铺+同品类]
  71 + List<String> diffShopImgSimilarSknsYoho = new ArrayList<>();
  72 + if (use_yoho_image && bigdataSimilarSkn != null && StringUtils.isNotEmpty(bigdataSimilarSkn.getDiffShopImgSimilarSknsYoho())) {
  73 + diffShopImgSimilarSknsYoho = searchLikeHelper.getDistinctSknList(bigdataSimilarSkn.getDiffShopImgSimilarSknsYoho());
  74 + }
  75 + searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopImgSimilarSknsYoho));
  76 +
  77 + //5.2)图片[性别+不同店铺+同品类]
66 List<String> diffShopImgSimilarSkns = new ArrayList<>(); 78 List<String> diffShopImgSimilarSkns = new ArrayList<>();
67 - if (bigdataSimilarSkn != null && StringUtils.isNotEmpty(bigdataSimilarSkn.getDiffShopImgSimilarSkns())) { 79 + if (!use_yoho_image && bigdataSimilarSkn != null && StringUtils.isNotEmpty(bigdataSimilarSkn.getDiffShopImgSimilarSkns())) {
68 diffShopImgSimilarSkns = searchLikeHelper.getDistinctSknList(bigdataSimilarSkn.getDiffShopImgSimilarSkns()); 80 diffShopImgSimilarSkns = searchLikeHelper.getDistinctSknList(bigdataSimilarSkn.getDiffShopImgSimilarSkns());
69 } 81 }
70 searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopImgSimilarSkns)); 82 searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopImgSimilarSkns));
71 83
72 - //5.2)有货图片相似[性别+不同店铺+同品类]  
73 - List<String> diffShopImgSimilarSknsYoho = new ArrayList<>();  
74 -// if (bigdataSimilarSkn != null && StringUtils.isNotEmpty(bigdataSimilarSkn.getDiffShopImgSimilarSknsYoho())) {  
75 -// diffShopImgSimilarSknsYoho = searchLikeHelper.getDistinctSknList(bigdataSimilarSkn.getDiffShopImgSimilarSknsYoho());  
76 -// }  
77 - searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopImgSimilarSknsYoho));  
78 -  
79 //5.3)行为[性别+不同店铺+同品类] 84 //5.3)行为[性别+不同店铺+同品类]
80 List<String> diffShopActionSimilarSkns = new ArrayList<>(); 85 List<String> diffShopActionSimilarSkns = new ArrayList<>();
81 if (bigdataSimilarSkn != null && StringUtils.isNotEmpty(bigdataSimilarSkn.getDiffShopActionSimilarSkns())) { 86 if (bigdataSimilarSkn != null && StringUtils.isNotEmpty(bigdataSimilarSkn.getDiffShopActionSimilarSkns())) {
@@ -84,15 +89,15 @@ public class SearchLikeNotInShopService { @@ -84,15 +89,15 @@ public class SearchLikeNotInShopService {
84 searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopActionSimilarSkns)); 89 searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopActionSimilarSkns));
85 90
86 //5.4)文字兜底[性别+不同店铺+文字相似性] 91 //5.4)文字兜底[性别+不同店铺+文字相似性]
87 - searchParams.add(this.buildCharactersSearchParam(productInfoInEs, Arrays.asList(productSkn), pageSize)); 92 + searchParams.add(this.buildCharactersSearchParam(productInfoInEs, viewNum));
88 93
89 // 6、获取搜索结果 94 // 6、获取搜索结果
90 List<List<Map<String, Object>>> queryResults = searchLikeHelper.queryProductLists(searchParams); 95 List<List<Map<String, Object>>> queryResults = searchLikeHelper.queryProductLists(searchParams);
91 96
92 // 7、处理图片和行为的顺序 97 // 7、处理图片和行为的顺序
93 - List<Map<String, Object>> diffShopImgSimilarProducts = searchLikeHelper.sortProductList(queryResults.get(0), diffShopImgSimilarSkns, pageSize / 2);  
94 - List<Map<String, Object>> diffShopImgSimilarProductsYoho = searchLikeHelper.sortProductList(queryResults.get(1), diffShopImgSimilarSknsYoho, pageSize / 2);  
95 - List<Map<String, Object>> diffShopActionSimilarProducts = searchLikeHelper.sortProductList(queryResults.get(2), diffShopActionSimilarSkns, pageSize / 2); 98 + List<Map<String, Object>> diffShopImgSimilarProducts = searchLikeHelper.sortProductList(queryResults.get(0), diffShopImgSimilarSkns, viewNum / 2);
  99 + List<Map<String, Object>> diffShopImgSimilarProductsYoho = searchLikeHelper.sortProductList(queryResults.get(1), diffShopImgSimilarSknsYoho, viewNum / 2);
  100 + List<Map<String, Object>> diffShopActionSimilarProducts = searchLikeHelper.sortProductList(queryResults.get(2), diffShopActionSimilarSkns, viewNum / 2);
96 List<Map<String, Object>> charsetSimilarProducts = queryResults.get(3); 101 List<Map<String, Object>> charsetSimilarProducts = queryResults.get(3);
97 102
98 // 8、获取临时结果 103 // 8、获取临时结果
@@ -101,8 +106,8 @@ public class SearchLikeNotInShopService { @@ -101,8 +106,8 @@ public class SearchLikeNotInShopService {
101 tempProductList.addAll(diffShopImgSimilarProductsYoho); 106 tempProductList.addAll(diffShopImgSimilarProductsYoho);
102 tempProductList.addAll(diffShopActionSimilarProducts); 107 tempProductList.addAll(diffShopActionSimilarProducts);
103 tempProductList.addAll(charsetSimilarProducts); 108 tempProductList.addAll(charsetSimilarProducts);
104 - if (tempProductList.size() > pageSize) {  
105 - tempProductList = SearchCollectionUtils.safeSubList(tempProductList, 0, pageSize); 109 + if (tempProductList.size() > viewNum) {
  110 + tempProductList = SearchCollectionUtils.safeSubList(tempProductList, 0, viewNum);
106 } 111 }
107 // 8.1 保留偶数 112 // 8.1 保留偶数
108 if (tempProductList.size() % 2 > 0) { 113 if (tempProductList.size() % 2 > 0) {
@@ -130,11 +135,11 @@ public class SearchLikeNotInShopService { @@ -130,11 +135,11 @@ public class SearchLikeNotInShopService {
130 * @param productSkns 135 * @param productSkns
131 * @return 136 * @return
132 */ 137 */
133 - private SearchParam builderSimilarSknSearchParam(JSONObject productInfoInEs, List<String> productSkns) { 138 + private SearchParam builderSimilarSknSearchParam(JSONObject productInfoInEs, List<String> productSkns){
134 // 1、设置SearchParam 139 // 1、设置SearchParam
135 SearchParam searchParam = new SearchParam(); 140 SearchParam searchParam = new SearchParam();
136 // 2)设置query和filter 141 // 2)设置query和filter
137 - searchParam.setFiter(this.builderSimilarSknFilter(productInfoInEs, productSkns)); 142 + searchParam.setFiter(this.buildSearchLikeNotInShopFilter(productInfoInEs, productSkns));
138 // 3、设置分页参数 143 // 3、设置分页参数
139 searchParam.setOffset(0); 144 searchParam.setOffset(0);
140 searchParam.setSize(productSkns.size()); 145 searchParam.setSize(productSkns.size());
@@ -144,50 +149,19 @@ public class SearchLikeNotInShopService { @@ -144,50 +149,19 @@ public class SearchLikeNotInShopService {
144 return searchParam; 149 return searchParam;
145 } 150 }
146 151
147 - private QueryBuilder builderSimilarSknFilter(JSONObject productInfoInEs, List<String> inProductSkns) {  
148 - String isGlobalInEs = productInfoInEs.getString(ProductIndexEsField.isGlobal);  
149 - boolean isGlobal = "Y".equalsIgnoreCase(isGlobalInEs);  
150 - BoolQueryBuilder boolFilter = searchLikeHelper.genDefaultSearchLikeFilter(null, isGlobal);  
151 - // 1)设置此SKN相关的性别过滤条件  
152 - String gender = productInfoInEs.getString(ProductIndexEsField.gender);  
153 - List<String> genderList = searchLikeHelper.getGenderInfo(gender);  
154 - if (genderList != null && !genderList.isEmpty()) {  
155 - boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.gender, genderList));  
156 - }  
157 - // 2)设置productskn  
158 - if (inProductSkns != null && !inProductSkns.isEmpty()) {  
159 - boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, inProductSkns));  
160 - }  
161 - // 3)设置品牌或店铺信息  
162 - Integer brandId = productInfoInEs.getInteger(ProductIndexEsField.brandId);  
163 - Integer shopId = productInfoInEs.getInteger(ProductIndexEsField.shopId);  
164 - if (searchLikeHelper.isLegalInteger(shopId)) {  
165 - boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.shopId, shopId));  
166 - } else if (searchLikeHelper.isLegalInteger(brandId)) {  
167 - boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.brandId, brandId));  
168 - }  
169 - // 4)同品类  
170 - Integer middleSortId = productInfoInEs.getInteger(ProductIndexEsField.middleSortId);  
171 - if (searchLikeHelper.isLegalInteger(middleSortId)) {  
172 - boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.middleSortId, middleSortId));  
173 - }  
174 - return boolFilter;  
175 - }  
176 -  
177 /** 152 /**
178 * 店铺外按文字找相似 153 * 店铺外按文字找相似
179 * 154 *
180 * @param productInfoInEs 155 * @param productInfoInEs
181 - * @param notProductSkns  
182 * @param pageSize 156 * @param pageSize
183 * @return 157 * @return
184 */ 158 */
185 - public SearchParam buildCharactersSearchParam(JSONObject productInfoInEs, List<String> notProductSkns, int pageSize) { 159 + public SearchParam buildCharactersSearchParam(JSONObject productInfoInEs, int pageSize) {
186 // 1、设置SearchParam 160 // 1、设置SearchParam
187 SearchParam searchParam = new SearchParam(); 161 SearchParam searchParam = new SearchParam();
188 // 2)设置query和filter 162 // 2)设置query和filter
189 searchParam.setQuery(this.buildeCharactersQueryBuilder(productInfoInEs, "30%")); 163 searchParam.setQuery(this.buildeCharactersQueryBuilder(productInfoInEs, "30%"));
190 - searchParam.setFiter(this.buildCharactersFilter(productInfoInEs, notProductSkns)); 164 + searchParam.setFiter(this.buildSearchLikeNotInShopFilter(productInfoInEs, null));
191 // 3、设置排序规则[按打分排序] 165 // 3、设置排序规则[按打分排序]
192 List<SortBuilder<?>> sortBuilders = new ArrayList<SortBuilder<?>>(); 166 List<SortBuilder<?>> sortBuilders = new ArrayList<SortBuilder<?>>();
193 sortBuilders.add(SortBuilders.scoreSort().order(SortOrder.DESC)); 167 sortBuilders.add(SortBuilders.scoreSort().order(SortOrder.DESC));
@@ -207,17 +181,21 @@ public class SearchLikeNotInShopService { @@ -207,17 +181,21 @@ public class SearchLikeNotInShopService {
207 return queryBuilder; 181 return queryBuilder;
208 } 182 }
209 183
210 - private BoolQueryBuilder buildCharactersFilter(JSONObject productInfoInEs, List<String> notProductSkns) { 184 + private BoolQueryBuilder buildSearchLikeNotInShopFilter(JSONObject productInfoInEs, List<String> inProductSkns) {
  185 + //1) 默认参数
  186 + String productSkn = productInfoInEs.getString(ProductIndexEsField.productSkn);
211 String isGlobalInEs = productInfoInEs.getString(ProductIndexEsField.isGlobal); 187 String isGlobalInEs = productInfoInEs.getString(ProductIndexEsField.isGlobal);
212 boolean isGlobal = "Y".equalsIgnoreCase(isGlobalInEs); 188 boolean isGlobal = "Y".equalsIgnoreCase(isGlobalInEs);
213 - BoolQueryBuilder boolFilter = searchLikeHelper.genDefaultSearchLikeFilter(notProductSkns, isGlobal);  
214 - // 1)设置此SKN相关的性别过滤条件 189 + BoolQueryBuilder boolFilter = searchLikeHelper.genDefaultSearchLikeFilter(Arrays.asList(productSkn), isGlobal);
  190 +
  191 + // 2)设置此SKN相关的性别过滤条件
215 String gender = productInfoInEs.getString(ProductIndexEsField.gender); 192 String gender = productInfoInEs.getString(ProductIndexEsField.gender);
216 List<String> genderList = searchLikeHelper.getGenderInfo(gender); 193 List<String> genderList = searchLikeHelper.getGenderInfo(gender);
217 if (genderList != null && !genderList.isEmpty()) { 194 if (genderList != null && !genderList.isEmpty()) {
218 boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.gender, genderList)); 195 boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.gender, genderList));
219 } 196 }
220 - // 2)设置品牌或店铺信息 197 +
  198 + // 3)设置品牌或店铺信息
221 Integer brandId = productInfoInEs.getInteger(ProductIndexEsField.brandId); 199 Integer brandId = productInfoInEs.getInteger(ProductIndexEsField.brandId);
222 Integer shopId = productInfoInEs.getInteger(ProductIndexEsField.shopId); 200 Integer shopId = productInfoInEs.getInteger(ProductIndexEsField.shopId);
223 if (searchLikeHelper.isLegalInteger(shopId)) { 201 if (searchLikeHelper.isLegalInteger(shopId)) {
@@ -225,7 +203,13 @@ public class SearchLikeNotInShopService { @@ -225,7 +203,13 @@ public class SearchLikeNotInShopService {
225 } else if (searchLikeHelper.isLegalInteger(brandId)) { 203 } else if (searchLikeHelper.isLegalInteger(brandId)) {
226 boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.brandId, brandId)); 204 boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.brandId, brandId));
227 } 205 }
228 - // 3)设置品类信息 206 +
  207 + // 4)设置productskn
  208 + if (CollectionUtils.isNotEmpty(inProductSkns)) {
  209 + boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, inProductSkns));
  210 + }
  211 +
  212 + // 5)同品类
229 Integer middleSortId = productInfoInEs.getInteger(ProductIndexEsField.middleSortId); 213 Integer middleSortId = productInfoInEs.getInteger(ProductIndexEsField.middleSortId);
230 if (searchLikeHelper.isLegalInteger(middleSortId)) { 214 if (searchLikeHelper.isLegalInteger(middleSortId)) {
231 boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.middleSortId, middleSortId)); 215 boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.middleSortId, middleSortId));