第三章 Elasticsearch Query DSL -- 查询
摘要
Elasticsearch 提供了基于JSON的完整查询DSL(Domain Specific Language)来定义查询。将查询DSL视为查询的ASL()。它由两种子句组成:
- 基本查询条件(Leaf query clauses):
filed
字段满足某一特定的值。包括:match
,term
,range
等 - 复合查询条件(Compound query clauses):由基本查询条件组合而成,并用逻辑方式组合多个查询:
bool
;或是更改查询条件的行为:constant_score
- Elasticsearch默认允许昂贵的查询:这种查询会耗费大量的系统资源,响应速度比较慢。可以在配置中禁止这类查询:
search.allow_expensive_queries=false
默认为true
查询子句的行为会有所不同,具体取决于它们是在查询上下文中使用或是在过滤上下文中使用
查询和过滤的上下文(context)
在查询上下文中使用查询子句以应对可能影响匹配文档得分(即文档匹配程度)的条件,并在过滤器上下文中使用所有其他查询子句。
相关性得分
默认情况下,Elasticsearch 按相关性得分对搜索结果进行排序,该得分衡量每个文档与查询条件的匹配程度。相关性得分是一个正浮点数_score
,会在搜索结果中mate
字段中返回。得分越高,相关度越高。虽然每种查询类型都会不同的计算相关性分数,但分数的计算还会取决于查询子句是在查询上下文中还是在过滤上下文中运行。
查询上下文
在查询上下文中,查询子句用于表示:某一文档与该查询子句的匹配程度如何。除了确定文档是否匹配之外,查询子句还计算_score
元字段中的相关性的分。在查询请求中,传递query
的参数。
过滤上下文
在过滤上下文中,查询子句表示:某一文档是否匹配过滤子句。答案很简单,只有是或否,不计算相关性得分。过滤主要用于过滤结构化数据。
Elasticsearch 会缓存常用的过滤器,用于提高性能。在查询请求中传递filter
参数。
示例(下面这些查询参数,后续会详述)
query
,指定查询条件bool
,组建符合查询must
,隶属于bool
,必须满足match
,包含:address这个字段中,包含Street这个单词filter
,筛选条件term
,精确等于:age=32
range
,区间查询:balance>=1000
查询请求
curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must": {
"match": {
"address": "Street"}},
"filter": [
{
"term": {
"age": 32 }},
{
"range": {
"balance": {
"gte": 1000 }}}
]
}
}
}
'
运行结果
{
"took" : 69,
"timed_out" : false,
"_shards" : {
"total" : 16,
"successful" : 16,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 22,
"relation" : "eq"
},
"max_score" : 0.95395315,
"hits" : [
{
"_index" : "bank",
"_type" : "_doc",
"_id" : "140",
"_score" : 0.95395315,
"_source" : {
"account_number" : 140,
"balance" : 26696,
"firstname" : "Cotton",
"lastname" : "Christensen",
"age" : 32,
"gender" : "M",
"address" : "878 Schermerhorn Street",
"employer" : "Prowaste",
"email" : "cottonchristensen@prowaste.com",
"city" <