DSL 即 Domain Specific Language,是ES的JSON结构查询语法。
这个查询语法总体上包含2个部分:
叶子查询:对字段进行match、term、range等条件匹配
复合查询:复合查询包装其他叶子查询或复合查询
另外要注意在ES中有些查询的开销是比较大的:
-
需要进行线性扫描的查询(类似全表扫描):
-
具有高预付成本的查询:
-
fuzzy
queries模糊查询 (wildcard
除外) -
regexp
queries正则查询
(wildcard
除外) -
prefix
queries前缀查询 (wildcard
除外 or 没有index_prefixes
的除外) -
wildcard
queries通配符查询 (wildcard
除外) -
range
queries范围查询 ontext
andkeyword
fields
-
- Joining queries
- deprecated geo-shapes对不推荐的地理形状的查询
-
每个文档的成本可能很高的查询:
可以通过将 search.allow_expensive_querys 设置为false(默认为true)的值来阻止执行此类查询。
Query and filter context 上下文
关于相关性得分:
默认情况下,ES根据相关性得分对匹配的搜索结果进行排序,相关性得分衡量每个文档与查询的匹配程度。
相关性分数是一个正浮点数,在_score元数据字段中返回。分数越高,文档的匹配程度就越高。
Query context:除了决定文档是否匹配外,还计算_score元数据字段中的相关性分数。
filter context:这种匹配是对 是或否 的匹配,因此不会计算得分。经常使用的过滤器将由Elasticsearch自动缓存,以提高性能。
看下面这个例子,
query表示查询的开始
bool和两个match子句用于query context,用于对每个文档的匹配程度进行评分
filter用于filter context,它们将过滤掉不匹配的文档,但不会影响匹配文档的分数。
GET /_search { "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }}, { "range": { "publish_date": { "gte": "2015-01-01" }}} ] } } }
Compound queries 复合查询
bool
query 以bool开始的复合查询,包含以下子查询
|
必须匹配,对得分起作用 |
|
必须匹配,起到过滤作用,属于 filter context ,对得分不起作用,过滤能起到缓存作用 |
|
表示可以匹配,对得分起作用。它有一个minimum_should_match属性,表示至少应该匹配的数量,当bool中没有must或filter时,minimum_should_match的默认值是1,否则是0 |
|
必须不匹配,它也属于 filter context 中的,因此对得分不起作用,也进行缓存 |
关于minimum_should_match的取值,参考如下
Type | Example | Description |
---|---|---|
Integer |
|
表示至少匹配3项 |
Negative integer |
|
表示总共的匹配项的数量 减去 2,例如10-2=7 |
Percentage |
|
表示总共的匹配项的数量的 75%,向下舍去并使用最小值(总共的匹配项的数量 和 向下舍去后的值),例如10*75%=7,1*75%=1 |
Negative percentage |
|
表示总共的匹配项的数量 减去 25%,百分比的值向下舍去,然后从总数中减去以确定最小值,例如10-10*25%=8,1-1*25%=1 |
Combination |
|
左边是正整数L,中间是<符号,右边是正的百分比R。 设 N=总共的匹配项的数量,如果N小于等于L,则要匹配的数量是L,否则相当于 R,例如N是3时,结果=3,N是10时,结果=9 |
Multiple combinations |
|
复合条件,中间用空格。在本例中:如果有1或2个项,则结果=2;如果有3-9个项,则结果=-25%;如果有9个以上的项,则结果=-3 |