内容简介:因业务需要,之前的个别后台搜索功能采用了wildcard通配搜索,虽然性能很差,但效果最好。但近日接到反馈,说是带有空格的搜索词无法通过wildcard匹配到结果。应用wildcard的字段是keyword类型,当搜索词是:”abc def”的时候无法找到结果,但是仅搜”abc”或者”def”则可以搜到。
因业务需要,之前的个别后台搜索功能采用了wildcard通配搜索,虽然性能很差,但效果最好。
但近日接到反馈,说是带有空格的搜索词无法通过wildcard匹配到结果。
应用wildcard的字段是keyword类型,当搜索词是:”abc def”的时候无法找到结果,但是仅搜”abc”或者”def”则可以搜到。
有一篇stackoverflow:https://stackoverflow.com/questions/29377705/elastic-wild-card-search-not-working-with-space ,说到wildcard只能支持单个term的通配,中间带有空格是不行的:
The wildcard query works only with a single token. What you are trying to do is to find one token followed by another token with the second token being specified by a prefix. This can be achieved by using match phrase prefix query. Your query would look like this:
QueryBuilders.matchPhrasePrefixQuery(ElasticSearchUtil.FIELDNAME, searchValue)
Please note that the searchValue
shouldn’t have “*” at the end.
我又查到了一个2011年的博客,提到了底层lucene对空格等特殊字符的处理问题:https://dismantledtech.wordpress.com/2011/05/15/handling-spaces-in-lucene-wild-card-searches/:
This caused a problem, because Lucene’s query parser interprets the space in the search term as a break in the actual query, and doesn’t include it in the search.
我们去查lucene官方手册,可以看到对于lucene来说,它的语法包含了一些特殊字符,如果我们希望让lucene把wildcard query的”abc def”视作一个整体,那么需要转移成”abc\ def”,这样lucene就不会认为空格是拆分2个term的意思了。
然而我经过实践发现,在ES5.X中即便转义也没有达到效果,我的 PHP 代码如下:
public function escape_query($text) { $regex = '/[\\+\\-\\&\\|\\!\\(\\)\\{\\}\\[\\]\\^\\"\\~\\*\\?\\:\\\\ ]/'; return preg_replace($regex, '\\\\$0', $text); }
所以,也许我们需要看一下ES在处理wildcard query的时候做了什么事情,这个留作TODO。
另外,在之前的博客我也说过,利用match phrase短语匹配并不能完美解决精确通配的问题,因为短语匹配也依赖分词,而类似”*abc de*”这样的通配,对于match phrase分词阶段是无解的,一定无法匹配到想要的文档。
博主无私的分享着知识,你愿意送他一顿热腾腾的早餐吗?
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- C++ 中的替换空格
- xml中的空格之完全解说
- ios – 用Objective-C替换空格
- objective-c – 按空格数分割NSString
- Javascript中的编码约定:在括号之间使用空格
- MySQL列名中包含斜杠或者空格的处理方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。