分页 + 模糊查询 有坑

当分页查询结合模糊匹配时,可能出现全匹配数据不在第一页的问题。本文通过一个品牌查询接口的案例,探讨了三种解决方案:增大分页大小、前后端联合处理和利用MySQL的函数进行排序优化,并最终通过函数实现期望的排序效果。

前言

不知道你有没有使用过Mysqllike语句,进行模糊查询?

不知道你有没有将查询结果,进行分页处理?

模糊查询,加上分页处理,会有意想不到的坑,不信我们继续往下看。

我之前提供过一个品牌查询接口,给前端品牌选择控件使用的。

当时为了性能考虑,怕前端控件因为一次性加载太多的品牌,而导致页面卡死。

因此,对品牌查询接口做了分页处理。

刚开始品牌表的数据比较少,没有出现什么问题。

后来,产品加需求了,在品牌下拉选择控件中,让用户可以输入自定义品牌。

在用户添加品牌前,需要先查一下,如果该品牌存在,则使用已有品牌。如果不存在,则新增品牌。(这里是精确匹配)

这个需求很简单,很容易实现了。

后来,产品又加需求了,需要按名称模糊查询品牌。

该功能上线后,使用了很长一段时间,也没啥问题。

突然,在不经意的某一天,这个功能却出问题了。

到底怎么回事呢?

1.案发现场

某一天下午,运营找到测试反馈一个问题说:明明品牌苏三,已经存在了,但用户输入关键字:苏三时,系统没有让用户直接选择已有品牌,而是添加了一个叫:苏三的自定义的品牌。

我过去一看,还真的有问题。

不一会儿,就定位到原因了,初步判断是分页的问题。

搜索关键字:苏三,竟然出现了好几页的数据,把我惊呆了,品牌表怎么多了这么多数据了。

我查了数据库,其实数据量并不是特别多,但有些品牌名称比较特殊,有些品牌名称是多个品牌名称拼接而成的,比如:苏三,李四 或者 苏三,李四,王五,这是一个品牌。

其实是品牌名称建的不规范导致的问题,但已经没法让运营修改品牌了,只能通过技术手段解决目前的问题。

查询第一页的数据sql:

select * from brand w
<think>嗯,用户想了解Elasticsearch中BoolQueryBuilder的模糊询用法。首先,我需要回忆一下BoolQueryBuilder的基本结构,它通常用于组合多个询条件,比如must、should、filter等。模糊询的话,Elasticsearch中有几种方法,比如wildcard、fuzzy、match query的fuzziness参数,或者query string query。 然后,用户可能需要具体的代码示例,尤其是使用Java API的情况。比如,如何用BoolQueryBuilder来组合模糊询条件。可能需要结合同的模糊询方式,比如wildcard使用通配符,fuzzy处理拼写错误,或者match query的模糊匹配。 还要注意引用中的信息,比如引用[2]提到了通配符模糊询和错误纠正,这可能对应wildcard和fuzzy询。引用[4]提到了时间处理的,但用户的问题是关于模糊询的,所以暂时需要考虑时间处理部分。 用户可能需要分步骤的说明,比如如何构建BoolQueryBuilder,添加同的模糊条件,以及注意事项,比如通配符询的性能问题,建议避免左模糊,或者使用fuzziness参数控制编辑距离。 另外,示例代码应该使用Java,并且展示如何将多个模糊条件组合到BoolQuery中。例如,在must子句中使用wildcard,在should中使用fuzzy,或者使用matchQuery的fuzziness。同时,需要提到分页处理,比如引用[3]中的scroll或search_after,但用户的问题可能更关注基本用法。 还需要考虑性能优化,比如避免过多通配符影响询速度,或者使用filter上下文来缓存结果。此外,是否需要在BoolQuery中组合精确询和模糊询,比如用must处理精确条件,用should处理模糊条件来提升相关性。 最后,生成相关问题,帮助用户进一步学习,比如性能优化、组合精确和模糊询、分页方法等。</think>### Elasticsearch BoolQueryBuilder模糊询使用详解 在Elasticsearch中,`BoolQueryBuilder` 用于组合多个询条件(如 `must`、`should`、`filter`),而模糊询可通过多种方式实现。以下是具体用法和示例: --- #### 一、模糊询的四种实现方式 1. **Wildcard通配符询** 使用 `*`(任意字符)和 `?`(单字符)匹配文本,适用于简单模糊匹配。 ```java BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() .must(QueryBuilders.wildcardQuery("fieldName", "*keyword*")); // 包含"keyword" ``` 2. **Fuzzy模糊纠错** 允许字符编辑距离(默认2),处理拼写错误。 ```java boolQuery.should(QueryBuilders.fuzzyQuery("fieldName", "keywrod") .fuzziness(Fuzziness.TWO)); // 允许最多2次字符变动 ``` 3. **Match Query模糊参数** 通过 `fuzziness` 参数实现模糊匹配。 ```java boolQuery.should(QueryBuilders.matchQuery("fieldName", "keyword") .fuzziness(Fuzziness.AUTO)); // 自动计算允许的编辑距离 ``` 4. **Query String语法** 支持Lucene询语法,直接集成到BoolQuery中。 ```java boolQuery.must(QueryBuilders.queryStringQuery("fieldName:*keyword*")); ``` --- #### 二、BoolQueryBuilder组合模糊询示例 ```java // 创建BoolQuery并组合多个条件 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() // 精确匹配(必须满足) .must(QueryBuilders.termQuery("status", "active")) // Wildcard模糊匹配(必须满足) .must(QueryBuilders.wildcardQuery("title", "*elastic*")) // Fuzzy纠错(满足则加分) .should(QueryBuilders.fuzzyQuery("content", "seach") .fuzziness(Fuzziness.ONE)) // 排除过期数据 .mustNot(QueryBuilders.rangeQuery("createTime").lt("2023-01-01")); // 执行询 SearchResponse response = client.prepareSearch("index_name") .setQuery(boolQuery) .setSize(10) .get(); ``` --- #### 三、关键注意事项 1. **性能优化** - 避免左模糊(如 `*keyword`),优先使用右模糊(如 `keyword*`)[^2] - 对精确匹配字段使用 `filter` 上下文提升缓存效率: ```java boolQuery.filter(QueryBuilders.termQuery("category", "tech")); ``` 2. **分页处理** 大数据量时使用 `scroll` 或 `search_after` 代替传统分页[^3]: ```java SearchRequest request = new SearchRequest("index_name") .scroll(TimeValue.timeValueMinutes(1L)); ``` 3. **字段类型限制** Wildcard和Fuzzy询仅适用于 `text` 或 `keyword` 类型字段[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值