ElasticSearch 接口:查询term、match、bool、filter 介绍

2022-04-22 0 By admin

一、精准查询term

term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇

1.1、term单值

字段只有一个值时候,用term关键词查询。

curl -XGET http://192.168.1.73:9200/xyerp/order/_search -H 'Content-Type: application/json' -d '
  {
   "query": {
   "term": {
     "biz_id": "1909190023901225"
    }
   }
  }

进一步优化查询,因为是精准查询,不需要查询进行评分计算,只希望对文档进行包括或排除的计算。
所以我们会使用 constant_score 查询以非评分模式来执行 term 查询并以一作为统一评分。推荐如下查询

{  
  "query" : {
    "constant_score" : {
     "filter" : {
      "term" : {
      "biz_id" : "1909190023901225"
      }  
    }
    }  
  }  
}

1.2、terms多值

字段有一多个值时候,用terms关键词查询,后跟数组

{
  "query":{
    "terms":{
    "biz_id":["1909190023901225"]
    }
  }
}

constant_score 以非评分模式查询,推荐如下查询

{ 
  "query" : {  
    "constant_score" : {  
     "filter" : {  
      "terms" : {  
      "biz_id" : ["1909190023901225","e1909190111365113"]  
      }  
    }  
    }  
  }  
  }

1.3、term多个字段

  {
  	"query": [{
  		"term": {
  			"biz_id": "1909190023901225"
  		}
  	}, {
  		"term": {
  			"name": "zhangsan"
  		}
  	}]
  }

二、匹配查询match

match和term的区别是:
match查询的时候,elasticsearch会根据你给定的字段提供合适的分析器。
而term查询不会有分析器分析的过程,match查询相当于模糊匹配,只包含其中一部分关键词就行。
同时还要注意match系列匹配时,datatype要设置为text,否则不会开启分词。

2.1、match

进行full text search或者exact value(非string字段或not_analyzed的字段),进行匹配,会对要查询的内容进行分词。
如es中存的merchant_id的值为”2500,2501,2502″,按照逗号分词。
match匹配时查询参数值param=”2500,2502″,会对param进行分词,分为2500和2502,对merchant_id的值进行匹配,默认是or,即或者的关系,匹配任意一个分词,就返回数据结果。

{
   "query": {
   "match": {
     "merchant_id": "2500,2502"
   }
   },
   "sort": [
   {
     "trade_finished_time": {
     "order": "desc"
     }
   }
   ]
  }'

2.2、match_all

匹配所有的, 当不给查询条件时,默认全查,匹配所有字段。

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

2.3、multi_match

同时对查询的关键词,多个字段同时进行匹配,只要其中一个字段匹配到值就返回结果
只要查询的字段merchant_id,_id字段值中任何一个包含2501,就返回对应结果

{
  "query":{
    "multi_match":{
    "query":"2501",
    "fields":["merchant_id","_id"]
    }
  }
  }

同时field还支持更为丰富的查询
在在fields中,按brandName(品牌名)、sortName(分类名)、productName(商品名)productKeyword(商品关键字),搜索“牛仔 弹力”关键词,brandName源值、拼音值、关键字值都是100分,sortName源值、拼音值80分,productName源值60分,productKeyword值20分,分值由高到低优先级搜索

{
  "query": {
  "multi_match": {
    "query": "牛仔 弹力",
    "fields": [
    "brandName^100",
    "brandName.brandName_pinyin^100",
    "brandName.brandName_keyword^100",
    "sortName^80",
    "sortName.sortName_pinyin^80",
    "productName^60",
    "productKeyword^20"
    ],
    "type": <multi-match-type>,
    "operator": "AND"
  }
  }
  }

2.4、match_phrase

match_phrase查询分析文本,并从分析文本中创建短语查询。
类似 match 查询, match_phrase 查询首先将查询字符串解析成一个词项列表,然后对这些词项进行搜索,但只保留那些包含全部搜索词项,且位置与搜索词项相同的文档。
即对给定的短语完整查询匹配,搜索到的结果集都必须包含给定的查询词组
如下,查询 quick brown、quick brown fox、 brown fox可以查询到,quick fox 查询不到

{  
    "query": {  
    "match_phrase": {  
      "title": "quick brown fox"  
    }  
    }  
  }

如下, 查询 a,b,a和b之间隔3个字符可以查询到,隔不是3个查询不到

{
  "query":{
    "match_phrase" :{
    "query":"a,b",
    "slop":3
    }
  }
  }

2.5、match_phrase_prefix

左前缀匹配,类似sql中的 like ‘zhang%’。如查询姓张的同学有哪些,zhang san,zhang san feng,都能返回结果集

{  
    "query": {  
    "match_phrase_prefix": {  
      "name": "zhang"  
    }  
    }  
  } 

三、bool查询

bool查询包含四种操作符,分别是must,should,must_not,query。它们均是一种数组,数组里面是对应的判断条件

  1. must: 必须匹配,与and等价。贡献算分
  2. must_not:必须不匹配,与not等价,常过滤子句用,但不贡献算分
  3. should: 选择性匹配,至少满足一条,与 OR 等价。贡献算分
  4. filter: 过滤子句,必须匹配,但不贡献算分
{  
  "query" : {  
    "filtered" : {  
    "filter" : {  
      "bool" : {  
      "should" : [  
        { "term" : {"merchant_id" : 100}},  
        { "term" : {"pay_type" : "3"}}  
      ],  
      "must_not" : {  
        "term" : {"trade_type" : "2"}  
      }  
      }  
    }  
    }  
  }  
  }'

四、filter查询

过滤器,会查询对结果进行缓存,不会计算相关度,避免计算分值,执行速度非常快。
如下, 查询出status为active的状态

{
  "query": {
  "bool": {
    "filter": {
    "term": {
    "status": "active"
    }
    }
  }
  }
  }

filter也常和range范围查询一起结合使用,range范围可供组合的选项

  1. gt : 大于
  2. lt : 小于
  3. gte : 大于等于
  4. lte :小于等于

如下,查询merchant_id值为2501下的交易数据

{
  "query": {
  "bool": {
    "must": {
    "term": {
    "merchant_id": "2501"
    }
    }, 
    "filter": {
    "range": {
    "trade_finished_time": {
    "from": "2019-09-01T00:00:00", 
    "to": "2019-09-30T23:59:59"
    }
    }
    }
  }
  }
  }

如下查询,must下匹配,filter进行过滤,range定义范围

{  
  "query": {  
    "bool": {  
    "must": [  
      {   
      "match": {   
        "title": "Search"   
        }  
      },  
      {   
      "match": {   
      "content": "Elasticsearch"   
      }  
      }  
    ],  
    "filter": [  
      {   
      "term": {   
        "status": "1"   
        }  
      },  
      {   
      "range": {   
        "publish_date": {   
        "gte": "2015-01-01"   
        }  
      }  
      }  
    ]  
    }  
   }  
  }  

五、常见查询场景

5.1、示例一

查询商户ID为3582,订单号为360102199003072618,按时间范围过滤,按下单时间倒序,每次查询100条

{
  "query": {
  "bool": {
  	"must": [{
  		"term": {
  			"merchant_id": "3582"
  		}
  	}, {
  		"term": {
  			"order_num": "360102199003072618"
  		}
  	}],
  	"filter": [{
  		"range": {
  			"order_time": {
  				"from": "2019-11-01T17:00:00+08:00",
  				"to": "2019-11-01T20:00:00+08:00"
  			}
  		}
  	}]
  }
  },
  "size": 100,
  "sort": [{
  "order_time": "desc"
  }]
  }

5.2、示例二

查询venderId值为1234,taskId为1234,字段itemCodes和templateCodes的值至少有一个match匹配到结果,才返回对应数据集。

即must下两个terms同时满足,should下两个match至少满足一条

{
  "bool": {
  "must": [{
  "terms": {
  	"venderId": ["1234"]
  	}
  },
  {
  "terms": {
  	"taskId": ["1234"]
  	}
  }
  ],
  "should": [{
  	"match": {
  		"itemCodes": {
  			"query": "12,124"
  		}
  	}
  	},
  	{
  	"match": {
  		"templateCodes": {
  			"query": "t123,t124,t125"
  		}
  	}
  }
  ]
  }
  }