吐槽,说实在ES的查询特定语言(DSL)确实很繁琐,而且版本也在不停的迭代,新的查询也是层出不穷。吐槽归吐槽,今天就来说下match和match_phrase的区别吧!
一、match
GET /_search
{
"query": {
"match": {
"message": "this is a test."
}
}
}
上面的语句表示查询message
字段中包含this
、is
、test
(被分成3个词)的三个单词,并且默认情况下这三个词之间是or
的关系,也就是只要这三个词中间任意一个包含都能匹配到结果。看到这里,你肯定有疑问了,既然默认是or
,那肯定还存在这and
的关系吧?
1. operator
是的,是有这种关系,其写法如下:
GET /_search
{
"query": {
"match": {
"message": {
"query": "this is a test.",
// and也可以换成or,那就等同于上面的写法
"operator": "and"
}
}
}
}
这样写之后查询的结果就是this
、is
、test
三个单词都必须包含才能匹配到结果。
2. fuzziness
其意思就是模糊查询,不过这个模糊查询与SQL中like
是有区别的。在SQL中,我要查询name字段中前缀为Smith的结果只需要这样写:
select * from t_user where t_name like 'Smith%';
但在ES中则则是这样的:
GET /_search
{
"query": {
"match": {
"hobbies": {
// 想查询football
"query": "footba66",
"fuzziness": "AUTO"
}
}
}
}
注意查询的football
字母长度为8,我这里写的是footba66
,也就是ll
用66
替代了,但依旧可以查询得到。其原因是因为ES中定义如下:
- 0~2个字符串长度
字符串长度为0到2之间时必须精确匹配,如a、BC。 - 3~5个字符串长度
字符串长度为3到5之间时,字符串中可替换的长度为1,如query可以写成quer1或者que1y等根据实际情况。 - 大于5字符串长度
字符串长度大于5时,字符串可替换的长度为2,如上面的football可以写成footba66或者footb7ll或者其它等。
3. zero_terms_query
这个关键词的用法在于ES在查询语句的时候默认会把一些无关紧要的单词(如are、to、of等等吧)忽略掉,而只查询有实际意义的词。但是有时候我们又希望ES在查询的时候不能对这些词忽略,因此可以加上这个,其效果等同于match_all
。比如下面的语句,全都是这样的单词,如果被忽略了岂不是什么都查询不到吗?
GET /_search
{
"query": {
"match": {
"message": {
"query": "to be or not to be.",
"operator": "and",
"zero_terms_query": "all"
}
}
}
}
需要注意的是zero_terms_query
默认是none
,就是忽略了。