|
|
package com.yoho.search.service;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Iterator;
|
|
|
import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
import org.elasticsearch.index.query.BoolFilterBuilder;
|
|
|
import org.elasticsearch.index.query.FilterBuilders;
|
|
|
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
|
|
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
|
|
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
|
|
|
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import com.yoho.search.dal.model.SearchParam;
|
|
|
import com.yoho.search.dal.model.SearchResult;
|
|
|
import com.yoho.search.index.Index;
|
|
|
import com.yoho.search.index.IndexClient;
|
|
|
import com.yoho.search.index.SearchCallback;
|
|
|
import com.yoho.search.index.service.IndexService;
|
|
|
import com.yoho.search.utils.PriceRangeUtils;
|
|
|
|
|
|
/**
|
|
|
* Created by YOHO on 15-11-2.
|
|
|
*/
|
|
|
@Service
|
|
|
public class SearchBaseService {
|
|
|
|
|
|
@Autowired
|
|
|
private IndexService indexService;
|
|
|
|
|
|
/**
|
|
|
* 执行检索
|
|
|
*
|
|
|
* @param indexName
|
|
|
* @param searchParam
|
|
|
* @return SearchResult 返回检索结果
|
|
|
*/
|
|
|
public SearchResult doSearch(final String indexName, final SearchParam searchParam) {
|
|
|
SearchResult searchResult = null;
|
|
|
Index firstIndex = indexService.getIndex(indexName);
|
|
|
if (firstIndex != null) {
|
|
|
searchResult = indexService.execute(new SearchCallback<SearchResult>() {
|
|
|
@Override
|
|
|
public SearchResult execute(IndexClient indexClient) {
|
|
|
return indexClient.search(indexName, searchParam);
|
|
|
}
|
|
|
}, firstIndex);
|
|
|
}
|
|
|
return searchResult;
|
|
|
}
|
|
|
|
|
|
// 构造通用的检索条件
|
|
|
public BoolFilterBuilder buildFilter(BoolFilterBuilder boolFilterBuilder, Map<String, String> paramMap) {
|
|
|
String key;
|
|
|
String field;
|
|
|
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
|
|
|
if (entry.getKey().startsWith("filter_")) {
|
|
|
key = entry.getKey();
|
|
|
field = key.substring(7, key.length());
|
|
|
String value = entry.getValue();
|
|
|
if (value.contains(",")) {
|
|
|
String[] values = value.split(",");
|
|
|
boolFilterBuilder.must(FilterBuilders.termsFilter(field, values));
|
|
|
} else {
|
|
|
boolFilterBuilder.must(FilterBuilders.termFilter(field, value));
|
|
|
}
|
|
|
} else if (entry.getKey().startsWith("not_filter_")) {
|
|
|
key = entry.getKey();
|
|
|
field = key.substring(11, key.length());
|
|
|
String value = entry.getValue();
|
|
|
if (value.contains(",")) {
|
|
|
String[] values = value.split(",");
|
|
|
boolFilterBuilder.mustNot(FilterBuilders.termsFilter(field, values));
|
|
|
} else {
|
|
|
boolFilterBuilder.mustNot(FilterBuilders.termFilter(field, value));
|
|
|
}
|
|
|
} else if (entry.getKey().startsWith("range_gte_")) {
|
|
|
key = entry.getKey();
|
|
|
field = key.substring(10, key.length());
|
|
|
boolFilterBuilder.must(FilterBuilders.rangeFilter(field).gte(entry.getValue()));
|
|
|
} else if (entry.getKey().startsWith("range_lte_")) {
|
|
|
key = entry.getKey();
|
|
|
field = key.substring(10, key.length());
|
|
|
boolFilterBuilder.must(FilterBuilders.rangeFilter(field).lte(entry.getValue()));
|
|
|
} else if (entry.getKey().startsWith("range_gt_")) {
|
|
|
key = entry.getKey();
|
|
|
field = key.substring(9, key.length());
|
|
|
boolFilterBuilder.must(FilterBuilders.rangeFilter(field).gt(entry.getValue()));
|
|
|
} else if (entry.getKey().startsWith("range_lt_")) {
|
|
|
key = entry.getKey();
|
|
|
field = key.substring(9, key.length());
|
|
|
boolFilterBuilder.must(FilterBuilders.rangeFilter(field).lt(entry.getValue()));
|
|
|
}
|
|
|
}
|
|
|
return boolFilterBuilder;
|
|
|
}
|
|
|
|
|
|
public List<AbstractAggregationBuilder> buildAggregations(Map<String, String> paramMap) {
|
|
|
List<AbstractAggregationBuilder> list = new ArrayList<AbstractAggregationBuilder>();
|
|
|
String key;
|
|
|
String field;
|
|
|
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
|
|
|
if (entry.getKey().startsWith("agg_")) {
|
|
|
key = entry.getKey();
|
|
|
field = key.substring(4, key.length());
|
|
|
if ("goods_price".equals(field)) {
|
|
|
list.add(AggregationBuilders.terms(field + "Agg").field(field).size(10000).order(Terms.Order.term(true)));
|
|
|
} else {
|
|
|
list.add(AggregationBuilders.terms(field + "Agg").field(field).size(1000));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
public List<Map<String, Object>> buildFilterResponseMap(MultiBucketsAggregation aggregation, String fieldName) {
|
|
|
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
|
|
|
Map<String, Object> map;
|
|
|
Iterator<? extends MultiBucketsAggregation.Bucket> itSizeAgg = aggregation.getBuckets().iterator();
|
|
|
while (itSizeAgg.hasNext()) {
|
|
|
MultiBucketsAggregation.Bucket lt = itSizeAgg.next();
|
|
|
map = new HashMap<String, Object>();
|
|
|
map.put(fieldName, lt.getKey());
|
|
|
list.add(map);
|
|
|
}
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
public Map<String, Object> getPriceResponseMap(MultiBucketsAggregation aggregation) {
|
|
|
Map<String, Object> priceMap = new LinkedHashMap<String, Object>();
|
|
|
if (aggregation.getBuckets().isEmpty())
|
|
|
return priceMap;
|
|
|
Iterator<? extends MultiBucketsAggregation.Bucket> itPriceAgg = aggregation.getBuckets().iterator();
|
|
|
int size = aggregation.getBuckets().size();
|
|
|
float[] prePrice = new float[size];
|
|
|
int i = 0;
|
|
|
while (itPriceAgg.hasNext()) {
|
|
|
prePrice[i] = Float.parseFloat(itPriceAgg.next().getKey());
|
|
|
i++;
|
|
|
}
|
|
|
float maxPrice = prePrice[i - 1];
|
|
|
List<Integer> intervals = PriceRangeUtils.getPriceInterval(prePrice, maxPrice);
|
|
|
size = intervals.size();
|
|
|
int j = 0;
|
|
|
for (j = 0; j < size - 1; j++) {
|
|
|
if (j > 0) {
|
|
|
priceMap.put((intervals.get(j) + 1) + "," + intervals.get(j + 1), "¥" + (intervals.get(j) + 1) + "-" + intervals.get(j + 1));
|
|
|
} else {
|
|
|
priceMap.put(intervals.get(j) + "," + intervals.get(j + 1), "¥" + intervals.get(j) + "-" + intervals.get(j + 1));
|
|
|
}
|
|
|
}
|
|
|
priceMap.put((intervals.get(j) + 1) + ",99999", "¥" + intervals.get(j) + "以上");
|
|
|
return priceMap;
|
|
|
}
|
|
|
|
|
|
public Map<String, Object> getGenderResponseMap(MultiBucketsAggregation aggregation) {
|
|
|
Map<String, Object> genderMap = new LinkedHashMap<String, Object>();
|
|
|
Iterator<? extends MultiBucketsAggregation.Bucket> itGenderAgg = aggregation.getBuckets().iterator();
|
|
|
while (itGenderAgg.hasNext()) {
|
|
|
MultiBucketsAggregation.Bucket ltGender = itGenderAgg.next();
|
|
|
String genderId = ltGender.getKey();
|
|
|
if ("1".equals(genderId)) {
|
|
|
genderMap.put("1,3", "BOYS");
|
|
|
} else if ("2".equals(genderId)) {
|
|
|
genderMap.put("2,3", "GIRLS");
|
|
|
} else {
|
|
|
genderMap.put("1,3", "BOYS");
|
|
|
genderMap.put("2,3", "GIRLS");
|
|
|
}
|
|
|
}
|
|
|
return genderMap;
|
|
|
}
|
|
|
} |
...
|
...
|
|