Elasticsearch Query DSL 怎么用?查询语法详解

文章导读
Previous Quiz Next 在 Elasticsearch 中,搜索是通过基于 JSON 的 query 进行的。一个 query 由两个子句组成 −
📋 目录
  1. Match All Query
  2. 全文查询
  3. Multi Match Query
  4. Query String Query
  5. Term Level Queries
  6. Range Query
  7. Compound Queries
  8. Geo Queries
A A

Elasticsearch - Query DSL



Previous
Quiz
Next

在 Elasticsearch 中,搜索是通过基于 JSON 的 query 进行的。一个 query 由两个子句组成 −

  • Leaf Query Clauses − 这些子句包括 match、term 或 range,它们在特定字段中查找特定值。

  • Compound Query Clauses − 这些 query 是 leaf query 子句与其他 compound query 的组合,用于提取所需信息。

Elasticsearch 支持大量 query 类型。一个 query 以 query 关键字开头,然后在 JSON 对象形式中包含条件和过滤器。下面描述了不同类型的 query。

Match All Query

这是最基本的 query;它返回所有内容,并且每个对象的 score 为 1.0。

POST /schools/_search
{
   "query":{
      "match_all":{}
   }
}

运行上述代码后,我们将得到以下结果 −

{
   "took" : 7,
   "timed_out" : false,
   "_shards" : {
      "total" : 1,
      "successful" : 1,
      "skipped" : 0,
      "failed" : 0
   },
   "hits" : {
      "total" : {
         "value" : 2,
         "relation" : "eq"
      },
      "max_score" : 1.0,
      "hits" : [
         {
            "_index" : "schools",
            "_type" : "school",
            "_id" : "5",
            "_score" : 1.0,
            "_source" : {
               "name" : "Central School",
               "description" : "CBSE Affiliation",
               "street" : "Nagan",
               "city" : "paprola",
               "state" : "HP",
               "zip" : "176115",
               "location" : [
                  31.8955385,
                  76.8380405
               ],
               "fees" : 2200,
               "tags" : [
                  "Senior Secondary",
                  "beautiful campus"
               ],
               "rating" : "3.3"
            }
         },
         {
            "_index" : "schools",
            "_type" : "school",
            "_id" : "4",
            "_score" : 1.0,
            "_source" : {
               "name" : "City Best School",
               "description" : "ICSE",
               "street" : "West End",
               "city" : "Meerut",
               "state" : "UP",
               "zip" : "250002",
               "location" : [
                  28.9926174,
                  77.692485
               ],
               "fees" : 3500,
               "tags" : [
                  "fully computerized"
               ],
               "rating" : "4.5"
            }
         }
      ]
   }
}

全文查询

这些查询用于搜索完整的文本主体,如一章内容或新闻文章。此查询根据与特定索引或文档关联的 analyser 工作。在本节中,我们将讨论不同类型的全文查询。

Match query

此查询将文本或短语与一个或多个字段的值进行匹配。

POST /schools*/_search
{
   "query":{
      "match" : {
         "rating":"4.5"
      }
   }
}

运行上述代码后,我们将得到如下所示的响应 −

{
   "took" : 44,
   "timed_out" : false,
   "_shards" : {
      "total" : 1,
      "successful" : 1,
      "skipped" : 0,
      "failed" : 0
   },
   "hits" : {
      "total" : {
         "value" : 1,
         "relation" : "eq"
      },
      "max_score" : 0.47000363,
      "hits" : [
         {
            "_index" : "schools",
            "_type" : "school",
            "_id" : "4",
            "_score" : 0.47000363,
            "_source" : {
               "name" : "City Best School",
               "description" : "ICSE",
               "street" : "West End",
               "city" : "Meerut",
               "state" : "UP",
               "zip" : "250002",
               "location" : [
                  28.9926174,
                  77.692485
               ],
               "fees" : 3500,
               "tags" : [
                  "fully computerized"
               ],
               "rating" : "4.5"
            }
         }
      ]
   }
}

Multi Match Query

此查询将文本或短语与多个字段进行匹配。

POST /schools*/_search
{
   "query":{
      "multi_match" : {
         "query": "paprola",
         "fields": [ "city", "state" ]
      }
   }
}

运行上述代码后,我们将得到如下所示的响应 −

{
   "took" : 12,
   "timed_out" : false,
   "_shards" : {
      "total" : 1,
      "successful" : 1,
      "skipped" : 0,
      "failed" : 0
   },
   "hits" : {
      "total" : {
         "value" : 1,
         "relation" : "eq"
      },
      "max_score" : 0.9808292,
      "hits" : [
         {
            "_index" : "schools",
            "_type" : "school",
            "_id" : "5",
            "_score" : 0.9808292,
            "_source" : {
               "name" : "Central School",
               "description" : "CBSE Affiliation",
               "street" : "Nagan",
               "city" : "paprola",
               "state" : "HP",
               "zip" : "176115",
               "location" : [
                  31.8955385,
                  76.8380405
               ],
               "fees" : 2200,
               "tags" : [
                  "Senior Secondary",
                  "beautiful campus"
               ],
               "rating" : "3.3"
            }
         }
      ]
   }
}

Query String Query

此查询使用 query parser 和 query_string 关键字。

POST /schools*/_search
{
   "query":{
      "query_string":{
         "query":"beautiful"
      }
   }
}  

运行上述代码后,我们将得到如下所示的响应 −

{
   "took" : 60,
   "timed_out" : false,
   "_shards" : {
      "total" : 1,
      "successful" : 1,
      "skipped" : 0,
      "failed" : 0
   },
   "hits" : {
      "total" : {
      "value" : 1,
      "relation" : "eq"
   },
.

Term Level Queries

这些查询主要处理结构化数据,如数字、日期和枚举。

POST /schools*/_search
{
   "query":{
      "term":{"zip":"176115"}
   }
}

运行上述代码后,我们将得到如下所示的响应 −

..
hits" : [
   {
      "_index" : "schools",
      "_type" : "school",
      "_id" : "5",
      "_score" : 0.9808292,
      "_source" : {
         "name" : "Central School",
         "description" : "CBSE Affiliation",
         "street" : "Nagan",
         "city" : "paprola",
         "state" : "HP",
         "zip" : "176115",
         "location" : [
            31.8955385,
            76.8380405
         ],
      }
   }
]   
..

Range Query

此查询用于查找具有给定值范围之间的值的对象。为此,我们需要使用诸如以下运算符:

  • gte − 大于等于
  • gt − 大于
  • lte − 小于等于
  • lt − 小于

例如,观察以下代码:

POST /schools*/_search
{
   "query":{
      "range":{
         "rating":{
            "gte":3.5
         }
      }
   }
}

运行上述代码后,我们将得到如下响应:

{
   "took" : 24,
   "timed_out" : false,
   "_shards" : {
      "total" : 1,
      "successful" : 1,
      "skipped" : 0,
      "failed" : 0
   },
   "hits" : {
      "total" : {
         "value" : 1,
         "relation" : "eq"
      },
      "max_score" : 1.0,
      "hits" : [
         {
            "_index" : "schools",
            "_type" : "school",
            "_id" : "4",
            "_score" : 1.0,
            "_source" : {
               "name" : "City Best School",
               "description" : "ICSE",
               "street" : "West End",
               "city" : "Meerut",
               "state" : "UP",
               "zip" : "250002",
               "location" : [
                  28.9926174,
                  77.692485
               ],
               "fees" : 3500,
               "tags" : [
                  "fully computerized"
               ],
               "rating" : "4.5"
            }
         }
      ]
   }
}

还存在其他类型的 term level 查询,例如:

  • Exists query − 如果某个字段具有非空值。

  • Missing query − 这与 exists query 完全相反,此查询搜索没有特定字段或字段具有空值的对象。

  • Wildcard or regexp query − 此查询使用正则表达式在对象中查找模式。

Compound Queries

这些查询是由不同查询使用 Boolean 运算符(如 and、or、not)或其他针对不同索引或具有函数调用等的查询集合合并而成。

POST /schools/_search
{
   "query": {
      "bool" : {
         "must" : {
            "term" : { "state" : "UP" }
         },
         "filter": {
            "term" : { "fees" : "2200" }
         },
         "minimum_should_match" : 1,
         "boost" : 1.0
      }
   }
}

运行上述代码后,我们将得到如下响应:

{
   "took" : 6,
   "timed_out" : false,
   "_shards" : {
      "total" : 1,
      "successful" : 1,
      "skipped" : 0,
      "failed" : 0
   },
   "hits" : {
      "total" : {
         "value" : 0,
         "relation" : "eq"
      },
      "max_score" : null,
      "hits" : [ ]
   }
}

Geo Queries

这些查询处理地理位置和地理点。这些查询有助于查找学校或其他任何靠近某个位置的地理对象。您需要使用 geo point 数据类型。

PUT /geo_example
{
   "mappings": {
      "properties": {
         "location": {
            "type": "geo_shape"
         }
      }
   }
}

运行上述代码后,我们会得到如下响应 −

{  "acknowledged" : true,
   "shards_acknowledged" : true,
   "index" : "geo_example"
}

现在我们将数据发布到上面创建的索引中。

POST /geo_example/_doc?refresh
{
   "name": "Chapter One, London, UK",
   "location": {
      "type": "point",
      "coordinates": [11.660544, 57.800286]
   }
}

运行上述代码后,我们会得到如下响应 −

{
   "took" : 1,
   "timed_out" : false,
   "_shards" : {
      "total" : 1,
      "successful" : 1,
      "skipped" : 0,
      "failed" : 0
   },
   "hits" : {
      "total" : {
         "value" : 2,
         "relation" : "eq"
      },
      "max_score" : 1.0,
      "hits" : [
         "_index" : "geo_example",
         "_type" : "_doc",
         "_id" : "hASWZ2oBbkdGzVfiXHKD",
         "_score" : 1.0,
         "_source" : {
            "name" : "Chapter One, London, UK",
            "location" : {
               "type" : "point",
               "coordinates" : [
                  11.660544,
                  57.800286
               ]
            }
         }
      ]
   }
}