Elasticsearch搜索匹配功能(一)

针对不同的数据类型,ES提供了很多搜索匹配功能:有完全匹配的term搜索,也有按范围匹配的range搜索,还有进行分词匹配的match搜索。本节将介绍这些功能的使用场景。

单个文档查询

查询单个文档时,需要指明文档的唯一性标识,类似于 MySQL 中数据的主键查询,请求实例如下:

GET /hotel/_doc/002

返回结果如下:

{
 "_index": "hotel",
 "_id": "002",
 "_version": 1,
 "_seq_no": 15,
 "_primary_term": 1,
 "found": true,
 "_source": {
   "title": "文雅酒店",
   "city": "北京",
   "price": 337
}
}

查询所有文档

查询所有文档,需要将doc替换为search,使用match_all查询。请求实例如下:

GET /hotel/_search

返回结果如下:t

{
 "took": 6,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
},
 "hits": {
   "total": {
     "value": 1,
     "relation": "eq"
  },
   "max_score": 1,
   "hits": [
    {
       "_index": "hotel",
       "_id": "002",
       "_score": 1,
       "_source": {
         "title": "文雅酒店",
         "city": "北京",
         "price": 337
      }
    }
  ]
}
}

term级别查询

1、term查询

term查询是结构化精准查询的主要查询方式,用于查询待查字段和查询值是否完全匹配,请求形式如下:

GET /${index_name}/_search
{
 "query":{
    "term": {
       "${field}":
      {
        "value":"${value}"
      }
    }
}
}

参数说明:

  • field和value分别代表字段名称和查询值,field的数据类型可以是数值型、布尔型、日期型、数组型及关键字等。

以下示例是查询住宿价格为500元的酒店,price字段为数值型数据:

GET /hotel/_search
{
 "query":{
    "term":{
      "price":{
        "value":"500"
      }
    }
}
}

以下示例是搜索城市为北京的酒店,city字段为关键字类型数据:

GET /hotel/_search
{
 "query":{
    "term":{
      "city":{
        "value":"北京"
      }
    }
  }
}

以下示例是搜索没有满房的酒店,full_room(满房状态)字段类型为布尔类型数据:

GET /hotel/_explain/001
{
 "query":{
    "term":{
      "full_room":{
        "value":"false"
      }
    }
  }
}

对于日期型的字段查询,需要按照该字段在mappings中定义的格式进行查询。

2、terms查询

terms查询是term查询扩展形式,用于查询一个或多个值与待查字段是否完全匹配,其请求形式如下:

GET /${index_name}/_search
{
 "query": {
   "terms": {
     "field":[
       "value1","value2"
    ]
  }
}
}

参数说明:

  • field代表待查字段名,value1和value2代表多个查询值,field的数据类型可以是数值型、布尔型、日期型、数组型及关键字等。

以下是搜索城市为城市为北京或者天津的酒店为例:

GET /hotel/_search
{
 "query":{
    "terms":{
       "city":[
          "北京","天津"
      ]
    }
}
}
3、range查询

range查询用于范围查询,一般是对数值型和日期型数据的查询。使用range进行范围查询时,用户可以按照需求中是否包含边界数值进行选项设置,可供组合的选项如下:

  • gt:大于

  • lt:小于

  • gte:大于或等于

  • lte:小于或等于

以下查询住宿价格在300-500元的酒店:

GET /hotel/_search
{
 "query":{
   "range":{
     "price":{
        "gte":300,
        "lte":500
    }
  }
}
}

以下查询住宿价格大于300(不含边界值)元的酒店:

GET /hotel/_search
{
 "query":{
   "range":{
     "price":{
        "gt":300
    }
  }
}
}

注意:使用range查询时,查询值必须符合该字段在mappings中设置的规范。例如:在酒店索引中,price字段是double类型,则range应该使用数值型或者数值类型的字符串形式,不能使用其他形式。

4、exists查询

使用exists查询字段不为空文档,字段不为空条件有:

  • 值存在且不是null

  • 值不是空数组

  • 值是空数组,但不是[null]

创建索引hotel_1:

PUT /hotel_1
{
 "mappings":{
    "properties":{
       "title":{
         "type":"text"
      },
       "tag":{
         "type":"keyword"
      }
    }
}
}

向该索引中分别写入3条字段为空的数据

#添加tag字段值为null的文档
POST /hotel_1/_doc/006
{
//写入tag为null的文档
 "title":"环球酒店",
 "tag":null
}
#添加tag字段是空数组的文档
POST /hotel_1/_doc/007
{
//写入tag为null的文档
 "title":"环球酒店",
 "tag":[]
}
#添加tag为数组,其中只有一个元素且元素为null的文档
POST /hotel_1/_doc/008
{
//写入tag为null的文档
 "title":"环球酒店",
 "tag":[null]
}

上面3种情况的数据使用exists查询都不命中:

GET /hotel_1/_search
{
 "query":{
   "exists":{
     "field":"tag"
  }
}
}

返回结果如下:

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

布尔值查询

布尔查询是常用的复合查询,它把多个子查询组合成一个布尔表达式,这些子查询之间的逻辑关系是与,即所有子查询的结果都为true时布尔查询的结果才为真。布尔查询支持的子查询有四种,各子查询的名称和功能如下表所示:

子查询名称 功能
must 必须匹配该查询条件
should 可以匹配查询条件
must not 必须不匹配该查询条件
filter 必须匹配过滤条件,不进行打分计算
1、must查询

must:多条件精确查询相当于mysql当中的and),所有的条件都要符合(where id = 1 and name = xxx)。以下示例使用must查询城市为北京并且价格在350-400元的酒店:

GET /hotel/_search
{
 "query": {
    "bool": {
       "must": [
          {
               "term": {//第一个查询
                 "city": {
                   "value": "北京"
                }
              }
            },
            {
                 "range": {//第二个查询
                   "price": {
                     "gte": 350,
                     "lte": 400
                    }
                }
            }
        ]
    }
}
}
2、must not查询

must_not:多条件精确查询相当于mysql当中的!=),所有的条件都要符合(where id != 13)。以下示例中使用must not查询城市不是北京也不是天津的酒店:

GET /hotel/_search
{
 "query": {
    "bool": {
       "must_not": [
          {
             "term": {
               "city": {
                 "value":"北京"
                }
            }
          },
          {
              "term":{
                "city": {
                  "value":"天津"
                }
              }
          }
        ]
    }
}
}
3、should查询

should:多条件精确查询相当于mysql当中的or),所有的条件都要符合(where id = 1 or name = xxx)。以下示例使用should查询城市为北京或者天津的酒店:

GET /hotel/_search
{
 "query": {
    "bool": {
       "should": [
          {
             "term": {
               "city": {
                 "value": "北京"
              }
            }
          },
          {
             "term": {
               "city": {
                 "value":"天津"
              }
            }
          }
        ]
    }
}
}
4、filter查询

filter过滤查询,以下使用filter的简单例子:

GET /hotel/_search
{
 "query": {
    "bool": {
       "filter": [
          {
              "term": {
                 "city": "北京"
              }
            },
          {
              "term": {
                 "full_room": false
            }
          }
        ]
    }
}
}

条件

原文始发于微信公众号(面试技术):Elasticsearch搜索匹配功能(一)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/186940.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!