这里介绍Elasticsearch 中的组合查询的使用细节,Elasticsearch支持类似于在SQL中使用AND、OR以及NOT的运算符,可以通过组合嵌套这些条件进行复杂的数据筛选。
数据准备
复用上篇文章的mapping和数据供这里的demo使用。
mapping:
PUT /phones
{
"mappings": {
"properties": {
"price":{
"type":"long"
},
"color":{
"type": "keyword"
},
"brand":{
"type": "keyword"
},
"release_date":{
"type": "date"
}
}
}
}
数据:
PUT /phones/_bulk
{"index":{}}
{"price":100,"color":"白色","brand":"小米","release_date":"2022-02-06"}
{"index":{}}
{"price":150,"color":"白色","brand":"小米","release_date":"2022-02-06"}
{"index":{}}
{"price":200,"color":"黑色","brand":"小米","release_date":"2022-02-08"}
{"index":{}}
{"price":250,"color":"黑色","brand":"小米","release_date":"2022-02-08"}
{"index":{}}
{"price":300,"color":"白色","brand":"华为","release_date":"2022-02-08"}
{"index":{}}
{"price":400,"color":"黑色","brand":"华为","release_date":"2022-02-10"}
{"index":{}}
{"price":500,"color":"灰色","brand":"华为","release_date":"2022-02-11"}
{"index":{}}
{"price":250,"color":"白色","brand":"苹果","release_date":"2022-02-11"}
filter的用法
在使用filter查询的时候,会使用一个二进制数组bitset保存倒排索引中的document list,符合条件的document置为1,不符合的document对应的位置为0,并且会将filter的bitset缓存起来,相同的filter条件进来的话会直接读取之前的bitset缓存,当document有新增或者修改的时候,Elasticsearch会维护对应的bitset。
filter是仅仅过滤需要的数据,不会使用TF/IDF进行分数计算。
filter会在普通的query之前执行,这是filter的效率更快,可以先过滤掉一些数据。
组合查询中的使用:查询品牌是小米,且价格大于等于200的手机。
GET /phones/_search
{
"query":{
"bool":{
"must":{
"term":{
"brand":"小米"
}
},
"filter":{
"range":{
"price":{
"gte":200
}
}
}
}
}
}
单独使用filter:搜索价格大于400的手机。
query里面不能直接用filter,需要包一层constant_score,表示忽略评分
GET /phones/_search
{
"query":{
"constant_score":{
"filter":{
"range":{
"price":{
"gte":400
}
}
}
}
}
}
bool组合查询
在bool中可以嵌套should、must、must_not,它们分别sql中的or、and、not条件。
搜索品牌是小米或者华为且发布日期不能是2022-02-08的手机。
GET /phones/_search
{
"query":{
"constant_score":{
"filter":{
"bool":{
"should":[
{
"term":{
"brand":"小米"
}
},
{
"term":{
"brand":"华为"
}
}
],
"must_not":[
{
"term":{
"release_date":"2022-02-08"
}
}
]
}
}
}
}
}
搜素品牌是苹果 或者品牌是小米且颜色为黑色的手机
GET /phones/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"brand": {
"value": "苹果"
}
}
},
{
"bool": {
"must": [
{
"term": {
"brand": {
"value": "小米"
}
}
},
{
"term": {
"color": {
"value": "黑色"
}
}
}
]
}
}
]
}
}
}
should和must 用法的总结
must和should平级的话,should的条件是不参与过滤数据的,只参与分数计算。这时的分数是must和should搜索对应的分数加起来除以must和should的总和。
默认情况下should的条件是可以一个都不满足的,可以通过mininum_should_match指定should中必须满足的条件个数。当没有must的时候,should必须匹配一个。
单独使用should:查询发布日期是2022-02-10或2022-02-11的手机
GET /phones/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"release_date": {
"value": "2022-02-10"
}
}
},
{
"term": {
"release_date": {
"value": "2022-02-11"
}
}
}
]
}
}
}
should和must同时使用,可以看到不存在满足should中条件的数据,但只要满足must条件的数据都会被返回。
GET /phones/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"brand": {
"value": "三星"
}
}
},
{
"term": {
"color": {
"value": "绿色"
}
}
}
],
"must": [
{
"term": {
"price": {
"value": 250
}
}
}
]
}
}
}
评分权重自定义
默认情况下每个must和should条件的权重都是1,可以通过boost进行权重的修改。文章来源:https://www.toymoban.com/news/detail-475239.html
这里必须要满足的条件是发布时间为2022-02-08,由于是term查询所以分数最低的是1,价格为200所占评分权重最高。文章来源地址https://www.toymoban.com/news/detail-475239.html
GET /phones/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"release_date": {
"value": "2022-02-08"
}
}
}
],
"should": [
{
"term": {
"brand": {
"value": "华为"
, "boost": 2
}
}
},
{
"term": {
"price": {
"value": "200",
"boost": 5
}
}
}
]
}
}
}
到了这里,关于Elasticsearch 组合查询的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!