应用场景
酒店预订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相关优化。