Merge branch 'zj_productanalysis' into 0710
Showing
10 changed files
with
581 additions
and
535 deletions
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)); |
-
Please register or login to post a comment