1 基于词项的查询
基于词项的查询:不需要分析阶段,对单个词项进行操作,在倒排索引中查找准确词项。
a.Terms Query
Terms Query:在给定字段内查询并返回准确符合一个或多个词项的查询结果。
GET /_search
{
"query": {
"terms": {
"user.id": {
"value": ["kimchi", "eel"]
}
}
}
}
- Field为选填项,可以不指定字段。
- Terms Query最多可以查询65536个词项。可以用 index.max_terms_count 更改配置,更改限制。
b.Fuzzy Query
Fuzzy Query:返回与给定词项相似的结果。相似程度用Levenshtein编辑距离来衡量。
GET /_search
{
"query": {
"fuzzy": {
"user.id": {
"value": "ki",
"fuzziness": "1",
"transpositions": true
}
}
}
}
1编辑距离指一个字符的变化,包括:
- 改变一个字母(box→fox)
- 缺失一个字母(black→lack)
- 插入一个字母(sic→sick)
- 颠倒两个相邻字母的顺序(act→cat)
Fuzzy Query会创建一系列可能出现的,编辑距离为1的变化后的词项,然后用这些词项进行精确查询以获得最终结果。
- 扩大模糊搜索范围:fuzziness可以修改查找时最大的编辑距离。
- 是否包含颠倒:transpositions可以选择是否在相似中包含颠倒两个相邻字母的顺序。
c.Wildcard Query
Wildcard Query:返回符合通配符表达式的查询结果。使用?代替单个字符,*代替零个或几个字符。
GET /_search
{
"query": {
"wildcard": {
"user.id": {
"value": "ki*y"
}
}
}
}
2 基于全文的查询
基于全文的查询:高层查询,要先了解字段映射的信息。如果查询一个未分析的精确值字符串字段,会将整个查询字符串作为单个词项对待。如果查询一个已分析的精确值字符串字段,会先将查询字符串传递到一个合适的分析器, 然后生成一个供查询的词项列表。
a.Match Query
Match Query:是一个高级全文查询,它既能处理全文字段,又能处理精确字段。Match Query主要的应用场景就是进行全文搜索,但无论需要查询什么字段, Match Query都应该会是首选的查询方式。
GET /_search
{
"query": {
"match": {
"message": {
"query": "salmon udon at Maroubra Junction"
"operator": "OR"
"minimum_should_match": 2
}
}
}
}
- 查询步骤:检查字段类型、分析查询字段、查找匹配文档、为每个文档评分。只要查询字段中的至少一个词能匹配,该文档就能匹配,被匹配的词项越多,文档就越相关。
- 提高精度的方法:默认情况下operator操作符为OR,改成AND可以让所有指定词项都必须匹配。
- 控制精度的方法:minimum_should_match最小匹配参数,可以指定必须匹配的词项数来表示一个文档是否相关。可设置为某个数字或百分数。
b.Query String Query
Query String Query:使用句法将给定的查询条件按And或Or的方式进行分析和拆分,返回包含查询字符串的结果。
GET /_search
{
"query": {
"query_string": {
"query": "salmon udon at Maroubra Junction",
"default_field": "food"
"allow_leading_wildcard": "OR"
"analyze_wildcard": 2
"operator": "OR"
}
}
}
- Allow leading wildcard和analyze wildcard支持在查询条件中包含通配符。使用?代替单个字符,*代替零个或几个字符。
Note:
带有通配符的查询会占用大量的内存,同时查询效率也会低,尤其是allow leading wildcard,因为所有的词项都会被查询一遍。
- 可以不指定field,default field是选填项,默认值为所有可以被term查询的字段。
c.Match Phrase Query
Match Phrase Query:会分析文本,再从分析后的文本中生成phrase查询。
GET /_search
{
"query": {
"match_phrase": {
"message": "salmon udon at Maroubra Junction"
}
}
}
3 复合查询
复合查询:组合查询语句,使查询结果符合多项标准,支撑更复杂的查询条件。
a.Bool Query
Bool Query:对查询语句进行与或非的组合。包含关键词must(and), should(or), must_not(not)。
POST _search
{
"query": {
"bool" : {
"must" : {
"term" : { "user.id" : "kimchy" }
},
"must_not" : {
"range" : {
"age" : { "gte" : 10, "lte" : 20 }
}
},
"should" : [
{ "term" : { "tags" : "env1" } },
{ "term" : { "tags" : "deployed" } }
],
"minimum_should_match" : 1
}
}
}
- 控制精度:minimum_should_match 可以是绝对的数值也可以是百分数。
Note:
- 百分数向下取,例:should语句有三条内容,若minimum_should_match=75%,会取2条。
- 绝对数值为1时是取1条而不会取成100%。
- 若布尔查询中只有should语句没有must语句,minimum_should_match默认为1;在有must语句时默认值为0。
- 控制词项的权重:boosting,分为positive和negative_boost。
- 默认的boosting为1。
- positive取值为大于等于1的值,但取值太大没有意义,最终会对词项权重做归一化。
- negative取值为0到1。
Table1 Comparison of ES Query Methods
类型 | 查询方法 | 解释 | 包含中文 | 包含中文+英文 | 单个字母(不构成单词) | 加通配符 | 包含大写字母 |
---|---|---|---|---|---|---|---|
基于词项 | TermsQuery | 精确查询,支持多字段查询 | 不支持中文查询 | 不支持 | 若能精确匹配则可以 | 不支持 | 若能精确匹配则可以 |
WildcardQuery | 通配符查询,可分析通配符 | 不支持中文查询 | 不支持 | 不支持 | 支持 | 不支持 | |
FuzzyQuery | 模糊查询,支持搜索相似字段 | 不支持中文查询 | 不支持 | 不支持 | 不支持 | 支持 | |
基于全文 | MatchQuery | 标准全文查询,先分词 | 支持中文查询 | 支持 | 不支持 | 不支持 | 支持 |
QueryStringQuery | 先分词再查询,可分析通配符 | 支持中文查询 | 支持 | 能查询,但无返回值 | 支持 | 支持 | |
MatchPhraseQuery | 针对短语的查询 | 支持中文查询 | 不支持 | 不支持 | 不支持 | 支持 |
Note:
保留字符包括 + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ / 查询中包含这些字符会返回错误。
Standard Analyzer会将GET变成get,用Match Query查询GET时,可以搜索到结果,但Terms Query只能精确匹配,所以搜索不到GET,需要将其转换为get。POST、PUT、DELETE等同理。
Reference List:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.html
https://stackoverflow.com/questions/23150670/elasticsearch-match-vs-term-query
https://godoc.org/gopkg.in/olivere/elastic.v3