项目中用到了阿里云的开放搜索,进行一下总结。
OpenSearch基于阿里巴巴自主研发的大规模分布式搜索引擎平台,该平台承载了阿里巴巴全部主要搜索业务,包括淘宝、天猫、一淘、1688、ICBU、神马搜索等业务。OpenSearch以平台服务化的形式,将专业搜索技术简单化、低门槛化和低成本化,让搜索引擎技术不再成为客户的业务瓶颈,以低成本实现产品搜索功能并快速迭代。
注册阿里云
在服务中找到开放搜索,添加到自己的产品和服务里面。
进入以后提示错误
这个时候就需呀设置
我选择继续使用accesskey
那就创建一个key
这次就可以进入开放搜索了
内部就是这个样子
创建
注意这里,我为了理解方便选择了手动创建。
literal 类型我觉的可以理解为文本,主键我没有选择这个。而是用的int类型
可以看不是主键的就可以有多种数据类型可供选择,
注意里面的索引,现在index 里包含了两个字段,也就是说会从这两个字段里面找到匹配的内容。
分词方式选择了默认的中文基础分词。
创建完成
之后激活就可以了,我选择的是最低配置,这个配置现在是处于免费里面的。
接下来就是要上传数据了
这里我选择通过文件上传,当然这只是测试的时候比较实用,正常大量数据的话需要SDK上传。
这是我的测试数据,json格式传送。
[
{
"fields": {
"test_id": 1,
"test_name": "香蕉 ",
"test_content": " 很好吃,深受女性喜爱的功效。"
},
"cmd": "ADD"
},
{
"fields": {
"test_id": 2,
"test_name": "苹果",
"test_content": " 可以减肥,适合需要减轻体重的人"
},
"cmd": "ADD"
},
{
"fields": {
"test_id": 3,
"test_name": "葡萄",
"test_content": "被称为黑珍珠,自古昏君最喜欢吃"
},
"cmd": "ADD"
},
{
"fields": {
"test_id": 4,
"test_name": "梨 ",
"test_content": "适合糖尿病人的水果"
},
"cmd": "ADD"
},
{
"fields": {
"test_id": 5,
"test_name": "西瓜",
"test_content": "夏天解暑神器"
},
"cmd": "ADD"
}
]
在配置好,搜索结果以后我们可以看到在搜索结构中查看。
现在这些都是都是通过界面调用的,下面需要写代码正常应用中调用。
需要引入的包
import com.alibaba.fastjson.JSON;
import com.aliyun.opensearch.CloudsearchClient;
import com.aliyun.opensearch.CloudsearchSearch;
import com.aliyun.opensearch.object.KeyTypeEnum;
CloudsearchClient client;//客户
public SearchResultJson search(String json) {
logger.info("--------------------openSearch搜索商品开始----------------------------");
SearchResultJson searchResultJson = new SearchResultJson();
int total = 0;
//创建客户端
try {
this.client = new CloudsearchClient(accesskey, secret , host, opts, KeyTypeEnum.ALIYUN);
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
Map<String, Object> data = new HashMap<String, Object>();
data = JSON.parseObject(json, Map.class);
CloudsearchSearch search = new CloudsearchSearch(client);
// 添加指定搜索的应用:
search.addIndex(appName);
// 指定搜索返回的格式。
search.setFormat("json");
if(data != null){
if(data.get("priceSort") != null && data.get("priceSort").equals("1")){//价格升序
// 设定排序方式 + 表示正序 - 表示降序
search.addSort("price", "+");
}else if(data.get("priceSort") != null && data.get("priceSort").equals("0")){//价格降序
search.addSort("price", "-");
}
if(data.get("saleNum") != null && data.get("saleNum").equals("1")){//销量升序
search.addSort("soldnum", "+");
}else if(data.get("saleNum") != null && data.get("saleNum").equals("0")){//销量降序
search.addSort("soldnum", "-");
}
if(data.get("keyword") != null && !"".equals(data.get("keyword").toString().trim())){//关键词
String keyword = data.get("keyword").toString().trim();
String tempKeyword = keyword.replaceAll("\\s{1,}", " ");
String[] keywords = tempKeyword.split(" ");
List<String> keywordList = new ArrayList<String>();
for(int i = 0; i < keywords.length; i++){
if(keywordList.contains(keywords[i]))
continue;
else
keywordList.add(keywords[i]);
}
keywords = keywordList.toArray(new String[keywordList.size()]);
StringBuilder text = new StringBuilder();
for(int i = 0; i < keywords.length; i++){
text.append("default:").append("'").append(keywords[i]).append("'").append(" AND ");
}
if(text.length()>0){
search.setQueryString("default:" + text.toString().substring(0, text.toString().lastIndexOf(" AND")));
}else{
search.setQueryString("default:" + text.toString());
}
search.setQueryString("default:'" + tempKeyword + "'");
}
if(data.get("lowPrice") != null && !"".equals(data.get("lowPrice").toString().trim())){//开始价格
search.addFilter("price>="+data.get("lowPrice"));
}
if(data.get("propertyStr") != null && !"".equals(data.get("propertyStr").toString().trim())){//开始价格
String propertyStr = (String) data.get("propertyStr");
String[] propertyArr = null;
if(propertyStr.contains(",")){
propertyArr = propertyStr.split(",");
for(int i = 0; i < propertyArr.length; i++){
StringBuilder text = new StringBuilder();
text.append('"').append(propertyArr[i]).append('"');
search.addFilter("property="+text.toString());
}
}else{
StringBuilder text = new StringBuilder();
text.append('"').append(data.get("propertyStr")).append('"');
search.addFilter("property="+text.toString());
}
}
if(data.get("hignPrice") != null && !"".equals(data.get("hignPrice").toString().trim())){//结束价格
search.addFilter("price<="+data.get("hignPrice"));
}
if(data.get("pageIndex") != null && !"".equals(data.get("pageIndex").toString().trim())){//页码
search.setStartHit(((int)data.get("pageIndex")-1) * 10);
}
if(data.get("supplierId") != null && !"".equals(data.get("supplierId").toString().trim())){//页码
search.addFilter("supplierid="+data.get("supplierId").toString().trim());
}
if(data.get("flag") != null && !"".equals(data.get("flag").toString().trim())){//页码
if(data.get("flag").equals(BY_SUPPLIER)){
search.addAggregate("listname2", "count()");
}else if(data.get("flag").equals(BY_COMMON)){
search.addAggregate("property", "count()");
}
}
search.setHits(10);
try {
Map<String, Object> tempResult = JSON.parseObject(search.search(),Map.class);
Map<String, Object> middleTempResult = (Map<String, Object>) tempResult.get("result");
total = (int) middleTempResult.get("total");//总数
//-----------------查询商品结果-------------------
List<Map<String, Object>> result = (List<Map<String, Object>>) middleTempResult.get("items");
logger.info("\n###搜索商品列表结果:" + result +"\n");
List<Product> products = new ArrayList<Product>();
for(Map<String, Object> object : result){
Product product = new Product();
String prodId = (String)object.get("prodid");
if(!StringUtils.isEmpty(prodId)){
product.setProdId(Long.parseLong(prodId));
}
product.setName((String)object.get("name"));
product.setCode((String)object.get("code"));
String price = (String)object.get("price");
if(!StringUtils.isEmpty(price)){
product.setPrice(new BigDecimal(price));
}
product.setDescription((String)object.get("description"));
product.setSupplierName((String)object.get("suppliername"));
product.setMainProdPicUrl((String)object.get("mainprodpicurl"));
String skuCount = (String)object.get("skucount");
product.setSkuCount(Integer.parseInt(skuCount));
product.setPropertyStr((String)object.get("propertystr"));
products.add(product);
}
//--------------------查询分类-------------
List<Map<String, Object>> facet = (List<Map<String, Object>>) middleTempResult.get("facet");//分类结果
logger.info("\n###搜索商品分类列表:" + facet +"\n");
List<Property> propertyList= new ArrayList<Property>();
if(data.get("flag") != null && !"".equals(data.get("flag").toString().trim())){//页码
if(data.get("flag").equals(BY_SUPPLIER)){
for(Map<String, Object> property : facet){
List<Map<String, Object>> properties = (List<Map<String, Object>>) property.get("items");
for(Map<String, Object> prop : properties){
String facetValue = (String) prop.get("value");
Long count = Long.parseLong((String) prop.get("count"));
Property propTemp = new Property();
propTemp.setName(facetValue);
propTemp.setCount(count);
propertyList.add(propTemp);
}
}
}else if(data.get("flag").equals(BY_COMMON)){
for(Map<String, Object> property : facet){
List<Map<String, Object>> properties = (List<Map<String, Object>>) property.get("items");
for(Map<String, Object> prop : properties){
String facetValue = (String) prop.get("value");
Long count = Long.parseLong((String) prop.get("count"));
Property propTemp = new Property();
propTemp.setName(facetValue.substring(0, facetValue.indexOf(":")));
propTemp.setValue(facetValue.substring(facetValue.indexOf(":")+1));
propTemp.setCount(count);
propertyList.add(propTemp);
}
}
}
}
searchResultJson.setProducts(products);
searchResultJson.setProperties(propertyList);
searchResultJson.setTotal(total);
} catch (ClientProtocolException e) {
logger.error("OpenSearch客户端协议异常!", e);
throw new PurchaseException(OperCodeDefine.OPEN_SEARCH_CLIENT_PROTOCOL_EXCEPTION, OperCodeDefine.OPEN_SEARCH_CLIENT_PROTOCOL_EXCEPTION_NAME);
} catch (UnknownHostException e) {
logger.error("创建OpenSearch客户端时发生异常:未知主机异常!", e);
throw new PurchaseException(OperCodeDefine.OPEN_SEARCH_UNKNOWN_HOST_EXCEPTION, OperCodeDefine.OPEN_SEARCH_UNKNOWN_HOST_EXCEPTION_NAME);
} catch (IOException e) {
logger.error("OpenSearch上传文档IO操作异常!", e);
throw new PurchaseException(OperCodeDefine.OPEN_SEARCH_IO_ERROR, OperCodeDefine.OPEN_SEARCH_IO_ERROR_NAME);
}
}
return searchResultJson;
}