Elasticsearch-查询表达式

来源:互联网 发布:精通c 游戏编程 pdf 编辑:程序博客网 时间:2024/06/08 09:02

查询表达式(QUERY DSL)是一种非常灵活又富有表现力的查询语言。Elasticsearch使用它可以以简单的JSON接口来展现搜索引擎功能的绝大部分。在你的应用中,你应该用它来编写你的查询语句。它可以使你的查询语句更灵活、更精确、易读和易调试。

要使用这种查询表达式,只需将查询条件传递给query参数:

{    "query":...}

空查询,查询索引库中所有的文档:

{}

等价于:

{    "query":{        "match_all":{}    }}

查询语句的结构

一个简单的查询语句,它的结构是:

{    QUERY_NAME:{        ARGUMENT:VALUE,        ARGUMENT:VALUE,        ...    }}

如果是针对某个字段,它的结构如下:

{    QUERY_NAME:{        FIELD_NAME:{            ARGUMENT:VALUE,            ARGUMENT:VALUE,            ...        }    }}

举个栗子,你可以使用match查询语句来查询name包含的所有数据:

{    "match":{        "name":"张"    }}

完整的请求体如下:

{    "query":{        "match":{            "name":"张"        }    }}

一些重要的查询

虽然Elasticsearch自带了很多的查询。但经常用到的就那么几个。接下来将介绍几个常用的查询:

match_all查询

match_all查询,为查询所有文档。在没有指定查询方式时,它是默认的查询:

{    "query":{        "match_all":{}    }}

match查询

无论你在任何字段上进行的是全文搜索还是精确值查询,match查询是你可用的标准查询。如果你在一个全文字段上使用match查询,在执行查询前,它将用正确的分析器去分析查询字符串:

{    "query":{        "match":{            "name":"张"        }    }}

multi_match查询

multi_match可以在多个字段上进行相同的match查询:

{    "multi_match":{        "query":"query info",        "fields":["name","addr"]    }}

range查询

range查询出落在指定区间内的时间或数字:

{    "range":{        "age":{            "gte":18,            "lte":22        }    }}

range查询相关区间运算符:
- gt:大于
- lt:小于
- gte:大于或等于
- lte:小于或等于

term查询

term查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些not analyzed的字符串:

{    "query":{        "term":{            "date":"2017-10-30"        }    }}

term查询对于输入的文本不分析,所以它将给定的值进行精确查询。它查询那些精确匹配的值(包括大小写,重音和空格等方面的差异)

terms查询

terms查询和term查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值的任何一个值,那么这个文档满足条件:

{    "query":{        "terms":{            "date":["2017-10-30","2017-10-31"]        }    }}

exists和missing查询

exists用于查询字段存在的文档,而missing用于查询字段不存在的文档。这与MongoDB中exists=trueexists=fasle有这相同的特性:

{    "query":{        "exists":{            "field":"name"        }    }}

上述栗子用于查询name字段存在的所有文档。

组合多查询

在现实的开发过程中,查询的需求往往没有那么简单,不可能只查询一个条件就能满足我们的需求,往往需要查询多个条件,同时满足或者满足其中一个或这两个条件才是我们所需要的。为了构建类似的高级查询,你需要有一种能将多查询组合成一个单一查询的方法。

你可以用bool查询来实现一系列需求。这种查询可以将多个查询组合在一起,成为用户自己所需要的bool查询,它接收一下参数:

  • must:文档必须匹配这些条件才能被包含进来
  • must_not:文档必须不匹配这些条件才能被包含进来
  • should:如果满足这些语句中的任意语句,将增加_score,否则将无任何影响
  • filter:必须匹配,但它以不评分、过滤模式来进行

举个栗子:

{    "query":{        "bool":{            "must":{"match":{"name":"laowang"}},            "must_not":{"term":{"age":18}},            "should":[                {                    "match":{                        "addr":"广东"                    }                },                {                    "match":{                        "addr":"广西"                    }                }            ]        }    }}

匹配name = laowang并且age != 18,并且addr=广东或者addr=广西的所有文档。如果文档满足should中的任一条件_score值将更高,排名将靠前。如果都满足,_score将会更高。排名更靠前

Elasticsearch默认是按照_score进行排序的,而_score的大小是根据文档的匹配程度来决定的,filter查询对查询到的所有文档不进行评分,即查询到的数据是无序的。bool也可以嵌套在filter中进行一个不评分的查询,如下所示:

{    "query":{        "bool":{            "must":{"match":{"name":"laowang"}},            "filter":{                "bool":{                    "must":{"match":{"age":18}}                }            }        }    }}

值得注意的是filter必须嵌套在bool或其他查询中,不可单独拿出来使用

验证查询语句是否合法

当我们执行一个很复杂的查询语句时,我们可以用validate-queryAPI来验证这个查询语句是否合法:

curl -XGET 'http://localhost:9200/csdn/blog/_validate/query' -d '{    "query":{        "name":{            "match":"laowang"        }    }}'

将会返回如下信息:

{  "valid": false}

validfalse表示,查询语句不合法。只有vaild信息是远远不够的,我们还需要知道错误的原因是什么?我们可以将explain参数添加到查询当中:

curl -XGET 'http://localhost:9200/csdn/blog/_validate/query?explain' -d '{    'query':{        "name":{            "match":"laowang"        }    }    }'

将返回如下信息:

{  "valid": false,  "error": "org.elasticsearch.common.ParsingException: no [query] registered for [name]"}

错误信息告诉我们,Elasticsearch中没有name查询表达式。