版本号:
用户会传入多个关键字去ES查询 字段 的多个字段,要求在返回的结果中被搜索的字段需要高亮所有匹配的关键字。例如同时通过和关键字,再 的列表中的和中搜索。如果有人员的中这两个关键字和都可以匹配到,那么返回的结果中同时高亮这和关键字
基础的ElasticSearch 字段的高亮实现搜可以参考https://blog.csdn.net/weixin_48990070/article/details/120342597 这篇笔记。
问题点1
对于同一个 字段支持在一个 用不同的关键字来搜索,但对于 查询只会高亮其中匹配的一个关键字,而不是全部。引入如果多关键字直接是任意满足的关系,则之后高亮匹配的其中的一个关键字,这个与不满足需求。
问题点2
那就把关键字拆分为多个 ,一个关键字对应一个 。但这个方法一样可以搜索,但对于同一个字段的 默认的 属性只能出现在一个中,不允许同一个字段的不同 都指定 ,如果一定要这么做,那么就会得到一个查询错误的提示,提示如下:
如果只在一个关键字的指定,那么最终的高亮结果只会有该的高亮,还是不满足要求。
问题点3
通过AI询问得知 有个 属性可以解决的情况,可以通过设置不同的 属性值来达到对同一个字段用不同 来做多关键字的高亮效果,但是这样里又出现了两个新的问题。
1、 有个 属性值不能重复,否则一样出的错误提示。
2、高亮 结果是按照 有个 属性值分组展示的,不像非会给一个最终多个关键字都高亮的结果。
转换下问题就是:
1、要根据关键字自动生成不重复 有个 属性值
2、对于同字段的高亮结果,要做高亮内容的合并。
因此只要解决了上面两个问题,就可以完成业务的需求了。
问题1解决方案
在将查询参数转换为ES Query语句的处理中,用Map来缓存每个字段的当前有几个,通过累计数量,来自动生成每个中的 有个 属性名,例如名称为 字段名+“-”+
因此就不能再使用静态方法来构建查询语句了,得用构建器了,下面就是构建器的部分实现
其他相关代码:
定义一个适用Lambda表达式的接口
定义搜索字段的枚举
定义搜索类型的枚举
使用方法
问题2解决方案
合并高亮的处理,这个问题实际就是:对于一个字符串,存在多个字符串,,,并且,,再过滤掉和 字符后是相同的字符串。现在需要将字符串,,, 合并为一个字符串。合并后的字符串需要满足:
1、过滤掉和 字符后同相同
2、所有在,,被和包围的子字符串,在同样被和包围
另外要保证一个点是原始的字符串不能本身就有或 这些字符串,这个可以通过对数据源头进行过滤就可以了。比如使用 过滤。
合并高亮字符串的具体的实现算法如下:
修改https://blog.csdn.net/weixin_48990070/article/details/120342597 这篇笔记中的替换高亮处理的代码,思路为每次只合并找到的第一个高亮内容,将它和当前的原始内容合并,并将合并后的内容替换掉原始内容。重复这个动作知道所有高亮的内容都被合并到当前的原始内容中。