吐槽,说实在ES的查询特定语言(DSL)确实很繁琐,而且版本也在不停的迭代,新的查询也是层出不穷。吐槽归吐槽,今天就来说下match和match_phrase的区别吧!

一、match

GET /_search
{
	"query": {
		"match": {
			"message": "this is a test."
		}
	}
}

上面的语句表示查询message字段中包含thisistest(被分成3个词)的三个单词,并且默认情况下这三个词之间是or的关系,也就是只要这三个词中间任意一个包含都能匹配到结果。看到这里,你肯定有疑问了,既然默认是or,那肯定还存在这and的关系吧?

1. operator

是的,是有这种关系,其写法如下:

GET /_search
{
	"query": {
		"match": {
			"message": {
				"query": "this is a test.",
				// and也可以换成or,那就等同于上面的写法
				"operator": "and"
			}
		}
	}
}

这样写之后查询的结果就是thisistest三个单词都必须包含才能匹配到结果。

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,也就是ll66替代了,但依旧可以查询得到。其原因是因为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,就是忽略了。

4. cutoff_frequency

5. synonyms