elasticsearch aggregations_Elasticsearch非常有用的功能---自动补齐的实现

实现的最终效果如下图百度搜索相似,输入词的时候返回提示。同时输入拼音也会有相同的提示效果。

de5ef27e061902df40c2c1803f65182c.png

completion使用

安装ik中文分词器:https://github.com/medcl/elasticsearch-analysis-ik

安装拼音分词器:https://github.com/medcl/elasticsearch-analysis-pinyin

定义关键词索引并自定义ik+pinyin分词器,要完成补全搜索,必须要用到特殊的数据类型completion,要汉字拼音都能补全,必须要使用自定义的ik+pinyin分词器。

PUT suggest{  "settings": {    "number_of_replicas": 0,    "number_of_shards": 1,    "analysis": {        "analyzer": {            "ik_pinyin_analyzer": {                "type": "custom",                "tokenizer": "ik_max_word",                "filter": ["my_pinyin", "word_delimiter"]            }        },        "filter": {            "my_pinyin": {                "type": "pinyin",                "first letter": "prefix",                "padding_char": " "            }        }    }      },  "mappings": {      "suggest": {          "properties": {              "keyword": {                  "type": "completion",                  "analyzer": "ik_pinyin_analyzer",                  "fields": {                      "key": {                          "type": "keyword"                      }                  }              },              "id": {                  "type": "keyword"              },              "createDate": {                  "type": "date",                  "format": "yyyy-MM-dd HH:mm:ss"              }          }      }  }    }

初始化部分数据

POST _bulk/?refresh=true{ "index": { "_index": "suggest", "_type": "suggest" }}{ "keyword": "项目"}{ "index": { "_index": "suggest", "_type": "suggest" }}{ "keyword": "项目进度"}{ "index": { "_index": "suggest", "_type": "suggest" }}{ "keyword": "项目管理"}{ "index": { "_index": "suggest", "_type": "suggest" }}{ "keyword": "项目进度及调整 汇总.doc_文档"}{ "index": { "_index": "suggest", "_type": "suggest" }}{ "keyword": "项目"}

使用suggest获取搜索补全建议,并对同一词语去重。

GET /suggest/_search{    "suggest": {        "my-suggest": {            "prefix": "项目",            "completion": {                "field": "keyword",                "size": 20,                "skip_duplicates": true            }        }    }}

Java实现搜索补全代码

/** * 获取相关搜索,最多返回9条 * @param key * @return */ public JSONObject getSearchSuggest(String key) {     CompletionSuggestionBuilder suggestion = SuggestBuilders             .completionSuggestion("keyword").prefix(key).size(20).skipDuplicates(true);     SuggestBuilder suggestBuilder = new SuggestBuilder();     suggestBuilder.addSuggestion("suggest", suggestion);     SearchResponse response = template.suggest(suggestBuilder, EsConstants.SUGGEST);     Suggest suggest = response.getSuggest();      Set keywords = null;     if (suggest != null) {         keywords = new HashSet<>();         List extends Suggest.Suggestion.Entry extends Suggest.Suggestion.Entry.Option>> entries = suggest.getSuggestion("suggest").getEntries();          for (Suggest.Suggestion.Entry extends Suggest.Suggestion.Entry.Option> entry: entries) {             for (Suggest.Suggestion.Entry.Option option: entry.getOptions()) {                 /** 最多返回9个推荐,每个长度最大为20 */                 String keyword = option.getText().string();                 if (!StringUtils.isEmpty(keyword) && keyword.length() <= 20) {                     /** 去除输入字段 */                     if (keyword.equals(key)) continue;                     keywords.add(keyword);                     if (keywords.size() >= 9) {                         break;                     }                 }             }         }     }     return ApiResult.OK(keywords, "获取推荐词组成功"); }         

热门搜索推荐

上面自定义的索引中,通过fields属性专门存储了类型为keyword的字段keyword.key。可以通过统计keyword.key来获取搜索次数最多的句子。下面是java实现方式

public JSONObject searchHot(Map map) {    Integer size = 10;    if (!StringUtils.isEmpty(map.get("size"))) {        size = (Integer)map.get("size");    }     /** 获取最近一个月时间 */    String preMonth = LocalDateTime.now().minusMonths(1).format(EsConstants.fomatter);    String now = LocalDateTime.now().format(EsConstants.fomatter);     /** 统计最近一个月的热门搜索,长度最大10,方便显示 */    SearchRequestBuilder requestBuilder = template.getClient().prepareSearch(EsConstants.SUGGEST)            .setQuery(QueryBuilders.rangeQuery("createDate").get(preMonth).lte(now));     SearchResponse searchResponse = requestBuilder.addAggregation(AggregationBuilders            .terms("hotSearch").field("keyword.key").size(size)).execute().actionGet();     Aggregations aggregations = searchResponse.getAggregations();    Set keywords = null;    if (aggregations != null) {        keywords = new HashSet<>();        Terms hotSearch = aggregations.get("hotSearch");        List extends Terms.Bucket> buckets = hotSearch.getBuckets();        for (Terms.Bucket bucket: buckets) {            if (bucket.getKey().toString().length() <= 10) {                 keywords.add((String)bucket.getKey());            }        }    }    return ApiResult.OK(keywords, "热门搜索获取成功");}   完整ElasticSearch教学代码:https://github.com/chutianmen/elasticsearch-examples完整ElasticSearch教学代码:https://github.com/chutianmen/elasticsearch-examples完整ElasticSearch教学代码:https://github.com/chutianmen/elasticsearch-examples完整ElasticSearch教学代码:https://github.com/chutianmen/elasticsearch-examples

完整ElasticSearch教学代码:https://github.com/chutianmen/elasticsearch-examples

好的,以下是一个简单的ElasticSearch聚合的Java API示例: ```java import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Client; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount; import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; public class ElasticSearchAggregationExample { public static void main(String[] args) { // 创建ElasticSearch客户端 Client client = // ...; // 构建查询条件 QueryBuilder query = QueryBuilders.boolQuery() .must(rangeQuery("timestamp").gte("2022-01-01T00:00:00").lte("2022-01-31T23:59:59")); // 构建聚合条件 AggregationBuilder aggregation = AggregationBuilders .dateHistogram("sales_over_time") .field("timestamp") .dateHistogramInterval(DateHistogramInterval.DAY) .subAggregation( AggregationBuilders .terms("product_types") .field("product_type") .subAggregation( AggregationBuilders.sum("total_sales").field("sales"), AggregationBuilders.count("transaction_count").field("transaction_id") ) ); // 执行查询 SearchResponse response = client.prepareSearch("my_index") .setQuery(query) .addAggregation(aggregation) .execute() .actionGet(); // 解析聚合结果 Histogram histogram = response.getAggregations().get("sales_over_time"); for (Histogram.Bucket bucket : histogram.getBuckets()) { System.out.println("Date: " + bucket.getKeyAsString()); Terms productTypes = bucket.getAggregations().get("product_types"); for (Terms.Bucket productType : productTypes.getBuckets()) { System.out.println("Product Type: " + productType.getKeyAsString()); Sum totalSales = productType.getAggregations().get("total_sales"); System.out.println("Total Sales: " + totalSales.getValue()); ValueCount transactionCount = productType.getAggregations().get("transaction_count"); System.out.println("Transaction Count: " + transactionCount.getValue()); } } // 关闭客户端 client.close(); } } ``` 这个示例通过ElasticSearch的Java API执行了一个聚合,其中包含了两层嵌套聚合,分别按照日期和产品类型对销售数据进行了汇总,输出了每个日期和产品类型的销售总额和交易次数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值