针对不同的数据类型,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