Elasticsearch全文檢索企業開發記錄總結(五):全文搜索

應用場景

酒店預訂app全文檢索

具體實現

1、 根據業務組建查詢條件參數:SearchParams

2、構建關鍵字查詢:keywordQuery

/**
     * 構建關鍵字查詢。
     * <p>
     * 從多個字段構建關鍵字查詢,包括拼音。
     *
     * @param keyword 關鍵字
     * @return 構建器
     */
    private MultiMatchQueryBuilder buildKeyWordQuery(String keyword) {
        // 關鍵字模糊匹配
        if (StringUtils.hasLength(keyword)) {
            String[] fields = {
//                    "name", "name.pinyin",
                    "cityName", "cityName.pinyin",
                    "areaName", "areaName.pinyin",
                    "streetName", "streetName.pinyin",
                    "address", "address.pinyin"
//                    "dictTypeByPositionName", "dictTypeByPositionName.pinyin",
//                    "dictTypeByServiceName", "dictTypeByServiceName.pinyin"
            };
            MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, fields);
            multiMatchQueryBuilder.field("name", 2.0f);
            multiMatchQueryBuilder.field("name.pinyin", 2.0f);
            multiMatchQueryBuilder.type(MultiMatchQueryBuilder.Type.PHRASE); // 短語匹配
            multiMatchQueryBuilder.slop(30); // 間隔30個詞也能查詢
            return multiMatchQueryBuilder;
        }
        return null;
    }

3、 構建範圍查詢:priceQuery(價格和時間等的查詢以範圍查詢rangeQuery爲載體)

    /**此處省略若干業務代碼**/

 QueryBuilders.rangeQuery("Price").gte(minPrice).lte(maxPrice)
                    )

    ...

4、 構建布爾查詢:boolQueryBuilder(構建完整查詢,所有的其他參數都以bool體現)

        ...

// 省份、地區
        String provinceCode = searchParams.getProvinceCode();
        String cityCode = searchParams.getCityCode(); 
        if (StringUtils.hasLength(provinceCode)) {
            boolQueryBuilder.must(QueryBuilders.termQuery("provinceCode", provinceCode));
        }
        if (StringUtils.hasLength(cityCode)) {
            boolQueryBuilder.must(QueryBuilders.termQuery("cityCode", cityCode));

        ...

5、查詢boolQueryBuilder過濾

以完整的查詢builder過濾價格priceQuery、時間條件等
        // ~ 價格查詢過濾
        // 其他條件加上價格和入住、離店時間條件
        String priceChildType = PRICE_INDEX_TYPE; // 父子查詢,價格作爲酒店的子項
        boolQueryBuilder.filter(QueryBuilders.hasChildQuery(priceChildType, priceQuery, ScoreMode.None));

6、構建排序SortBuilders

根據業務進行①定位位置、②酒店評分、③時間等進行排序構建SortBuilders

7、組建分頁

        int curPage = searchParams.getCurrentPage();
        int pageSize = searchParams.getPageSize();
        int from = (curPage - 1) * pageSize;

8、調用之前寫好的API執行查詢

 // ~ 執行查詢
SearchResponse sr = esService.search(HOTEL_INDEX_NAME,HOTEL_INDEX_TYPE, searchSourceBuilder, boolQueryBuilder,null, from, pageSize, null, sortBuilders.toArray(new SortBuilder[sortBuilders.size()]));

9、處理檢索處理結果

根據業務需求對ES檢索結果進行結果處理和頁面展示。

總結

到此,Elasticsearch全文檢索企業實戰的開發記錄完畢,本次開發記錄的更多的是程序結構設計的思想,以及實戰的架構設計。目前系統運行性能良好,後期會記錄Elasticsearch相關優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章