elasticsearch之全文搜索

1.场景还原

   近期,笔者项目中需要通过关键字来搜索与之相关的数据,es的全文搜索终于派上用场了!

2.准备步骤

①原理分析:

     es主要采用倒排索引,即每一个文档都对应一个ID。倒排索引会按照指定语法对每一个文档进行分词,然后维护一张表,列举所有文档中出现的terms以及它们出现的文档ID和出现频率。搜索时同样会对关键词进行同样的分词分析,然后查表得到结果。

②先下载与项目中es版本对应的ik中文分词器,https://github.com/medcl/elasticsearch-analysis-ik

③在es的plugins目录下创建ik,然后解压缩ik

④在elasticsearch.yml配置ik属性

index.analysis.analyzer.default.tokenizer : "ik_max_word"
index.analysis.analyzer.default.type : "ik"

3.实现方案

/**
 * 全文索引
 * @param index
 * @param type
 * @return
 */
public List hotCitySearchByEs(String index, String type,String startCity, String endCity,SortBuilder sortBuilder,QueryBuilder queryBuilder,Integer pageNo,Integer pageSize) {
       TransportClient  client = getClient();
        //查询条件 在匹配文字的时候一定用matchQuery termQuery 用于精确匹配 匹配数字 ,long型 term查询不会分词
        //matchQuery自带分词;
        //termQuery不带分词器
    QueryBuilder qb = boolQuery().must(termQuery("pinStartPoint", startCity))
                                 .must(termQuery("pinEndPoint", endCity));

                //索引
        SearchResponse response = client.prepareSearch(index)
                //type
                .setTypes(type)
                //搜索类型
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                // Query
                .setQuery(qb)
                //排序
                .addSort(sortBuilder)
                //过滤
                .setPostFilter(queryBuilder)
                //分页
                .setFrom(pageNo).setSize(pageSize).setExplain(true)
                //执行
                .execute()
                .actionGet();

    return response2List(client,response);

}
/**
 * 将查询后获得的response转成list
 * @param client
 * @param response
 * @return zx
 */
public static List response2List(TransportClient client,SearchResponse response){
    SearchHits hits = response.getHits();
    List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
    for (int i = 0; i < hits.getHits().length; i++) {
        BigDecimal geoDis = new BigDecimal((Double) hits.getAt(i).getSortValues()[0]);
        Map<String, Object> map = hits.getAt(i).getSource();
        map.put(EsProperties.ES_SERVICE_DISTANCE_TO,geoDis);
        list.add(map);
    }
    client.close();
    return list;
}

好了,今天点到为止,我是张星,欢迎加入博主技术交流群,群号:526601468

发布了215 篇原创文章 · 获赞 375 · 访问量 97万+

猜你喜欢

转载自blog.csdn.net/zhangxing52077/article/details/84326270