ElasticSearch系列 - SpringBoot整合ES:组合多个查询条件 bool 查询

文章目录

      • [01. ElasticSearch 布尔查询是什么?](#01. ElasticSearch 布尔查询是什么?)
      • [02. ElasticSearch 布尔查询有哪些类型?](#02. ElasticSearch 布尔查询有哪些类型?)
      • [03. ElasticSearch bool must 组合多个查询条件?](#03. ElasticSearch bool must 组合多个查询条件?)
      • [04. ElasticSearch bool should 组合多个查询条件?](#04. ElasticSearch bool should 组合多个查询条件?)
      • [05. ElasticSearch bool must_not 组合多个查询条件?](#05. ElasticSearch bool must_not 组合多个查询条件?)
      • [06. ElasticSearch bool 组合多个查询条件?](#06. ElasticSearch bool 组合多个查询条件?)
      • [07. ElasticSearch bool 过滤器是否支持嵌套查询?](#07. ElasticSearch bool 过滤器是否支持嵌套查询?)
      • [08. ElasticSearch bool must 组合多个查询条件?](#08. ElasticSearch bool must 组合多个查询条件?)
      • [09. SpringBoot整合ES实现bool查询](#09. SpringBoot整合ES实现bool查询)

01. ElasticSearch 布尔查询是什么?

在实际应用中,我们很有可能会查询多个值或字段。 一个 bool 查询由三部分组成:

js 复制代码
{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : [],
   }
}

must:所有的语句都必须(must) 匹配,与 AND 等价。

must_not:所有的语句都不能(must not)匹配,与 NOT 等价。

should:至少有一个语句要匹配,与 OR 等价。

02. ElasticSearch 布尔查询有哪些类型?

Elasticsearch布尔查询有三种类型:must查询、should查询和must_not查询。

① must查询:所有的查询条件都必须匹配才能返回文档。如果有任何一个查询条件不匹配,则该文档将被排除。

② should查询:至少有一个查询条件匹配时就可以返回文档。如果所有的查询条件都不匹配,则该文档将被排除。should查询可以设置一个minimum_should_match参数,用于指定至少需要匹配多少个查询条件才能返回文档。

③ must_not查询:所有的查询条件都必须不匹配才能返回文档。如果有任何一个查询条件匹配,则该文档将被排除。

这些布尔查询类型可以组合在一起,以便更精确地过滤文档。例如,您可以使用bool查询来组合多个must查询和should查询,以便同时满足多个查询条件。

03. ElasticSearch bool must 组合多个查询条件?

must查询:所有的查询条件都必须匹配才能返回文档。如果有任何一个查询条件不匹配,则该文档将被排除。

① 索引文档,构造数据:

json 复制代码
PUT /my_index
{
  "mappings": {
    "properties": {
      "createTime":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "tag":{
        "type": "keyword"
      },
      "price":{
        "type": "integer"
      }
    }
  }
}

PUT /my_index/_doc/1
{
  "createTime": "2023-03-29 10:30:11",
  "tag": "tag1",
  "price": 10
}

PUT /my_index/_doc/2
{
  "createTime": "2023-03-29 10:35:11",
  "tag": "tag2",
  "price": 20
}

PUT /my_index/_doc/3
{
  "createTime": "2023-03-29 10:38:11",
  "tag": "tag3",
  "price": 30
}

② 查询 tag 字段值为 tag1 并且 price 字段的值在10到20之间的文档,两个条件同时满足的文档才会返回:

json 复制代码
GET /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "tag": {
              "value": "tag1"
            }
          }
        },
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}

04. ElasticSearch bool should 组合多个查询条件?

should查询:至少有一个查询条件匹配时就可以返回文档。如果所有的查询条件都不匹配,则该文档将被排除。should查询可以设置一个minimum_should_match参数,用于指定至少需要匹配多少个查询条件才能返回文档。

① 索引文档,构造数据:

json 复制代码
PUT /my_index
{
  "mappings": {
    "properties": {
      "createTime":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "tag":{
        "type": "keyword"
      },
      "price":{
        "type": "integer"
      }
    }
  }
}

PUT /my_index/_doc/1
{
  "createTime": "2023-03-29 10:30:11",
  "tag": "tag1",
  "price": 10
}

PUT /my_index/_doc/2
{
  "createTime": "2023-03-29 10:35:11",
  "tag": "tag2",
  "price": 20
}

PUT /my_index/_doc/3
{
  "createTime": "2023-03-29 10:38:11",
  "tag": "tag3",
  "price": 30
}

② 查询 tag 字段值为 tag1 或者 price 字段的值在10到20之间的文档,两个条件只要有一个满足的文档就会返回:

json 复制代码
GET /my_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "tag": {
              "value": "tag1"
            }
          }
        },
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}
json 复制代码
{
  "took" : 13,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.9808292,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.9808292,
        "_source" : {
          "createTime" : "2023-03-29 10:30:11",
          "tag" : "tag1",
          "price" : 10
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "createTime" : "2023-03-29 10:35:11",
          "tag" : "tag2",
          "price" : 20
        }
      }
    ]
  }
}

③ 在ElasticSearch的Bool查询中,可以使用should查询来指定多个查询条件,表示至少有一个条件必须匹配。同时,可以使用minimum_should_match参数来指定至少有多少个条件必须匹配。

查询 tag 字段值为 tag1 或者 price 字段的值在10到20之间的文档,并且至少有两个条件必须匹配:

json 复制代码
GET /my_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "tag": {
              "value": "tag1"
            }
          }
        },
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ],
      "minimum_should_match": 2
    }
  }
}
json 复制代码
{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.9808292,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.9808292,
        "_source" : {
          "createTime" : "2023-03-29 10:30:11",
          "tag" : "tag1",
          "price" : 10
        }
      }
    ]
  }
}

05. ElasticSearch bool must_not 组合多个查询条件?

must_not查询:所有的查询条件都必须不匹配才能返回文档。如果有任何一个查询条件匹配,则该文档将被排除。

① 索引文档,构造数据:

json 复制代码
PUT /my_index
{
  "mappings": {
    "properties": {
      "createTime":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "tag":{
        "type": "keyword"
      },
      "price":{
        "type": "integer"
      }
    }
  }
}

PUT /my_index/_doc/1
{
  "createTime": "2023-03-29 10:30:11",
  "tag": "tag1",
  "price": 10
}

PUT /my_index/_doc/2
{
  "createTime": "2023-03-29 10:35:11",
  "tag": "tag2",
  "price": 20
}

PUT /my_index/_doc/3
{
  "createTime": "2023-03-29 10:38:11",
  "tag": "tag3",
  "price": 30
}

② 查询 tag 字段不等于tag1 并且 price 字段的值不在10到20之间的文档:

json 复制代码
GET /my_index/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "term": {
            "tag": {
              "value": "tag1"
            }
          }
        },
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}
json 复制代码
{
  "took" : 14,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.0,
        "_source" : {
          "createTime" : "2023-03-29 10:38:11",
          "tag" : "tag3",
          "price" : 30
        }
      }
    ]
  }
}

06. ElasticSearch bool 组合多个查询条件?

① 索引文档,构造数据:

json 复制代码
PUT /my_index
{
  "mappings": {
    "properties": {
      "createTime":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "tag":{
        "type": "keyword"
      },
      "price":{
        "type": "integer"
      }
    }
  }
}

PUT /my_index/_doc/1
{
  "createTime": "2023-03-29 10:30:11",
  "tag": "tag1",
  "price": 10
}

PUT /my_index/_doc/2
{
  "createTime": "2023-03-29 10:35:11",
  "tag": "tag2",
  "price": 20
}

PUT /my_index/_doc/3
{
  "createTime": "2023-03-29 10:38:11",
  "tag": "tag3",
  "price": 30
}

② 查询 tag 字段的值不为tag1 ,且createTime的值为"2023-03-29 10:38:11",或者 price 字段的值在10到20之间的文档:

json 复制代码
GET /my_index/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "term": {
            "tag": {
              "value": "tag1"
            }
          }
        }
      ],
      "should": [
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ],
      "must": [
        {
          "term": {
            "createTime": {
              "value": "2023-03-29 10:38:11"
            }
          }
        }
      ]
    }
  }
}
json 复制代码
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "createTime" : "2023-03-29 10:38:11",
          "tag" : "tag3",
          "price" : 30
        }
      }
    ]
  }
}

07. ElasticSearch bool 过滤器是否支持嵌套查询?

① 构造数据:

json 复制代码
PUT /my_index
{
  "mappings": {
    "properties": {
      "createTime":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "tag":{
        "type": "keyword"
      },
      "price":{
        "type": "integer"
      }
    }
  }
}

PUT /my_index/_doc/1
{
  "createTime": "2023-03-29 10:30:11",
  "tag": "tag1",
  "price": 10
}

PUT /my_index/_doc/2
{
  "createTime": "2023-03-29 10:35:11",
  "tag": "tag2",
  "price": 20
}

PUT /my_index/_doc/3
{
  "createTime": "2023-03-29 10:38:11",
  "tag": "tag3",
  "price": 30
}

② 执行 bool 嵌套查询:

条件1:tag字段的值为tag2

条件2:price 字段的值为10 并且 createTime 字段的值为 "2023-03-29 10:30:11"

条件1 和 条件2 为或的关系

json 复制代码
GET /my_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "tag": "tag2"
          }
        },
        {
          "bool": {
            "must": [
              {
                "term": {
                  "price": 10
                }
              },
              {
                "term": {
                  "createTime": "2023-03-29 10:30:11" 
                }
              }
            ]
          }
        }
      ]
    }
  }
}

外部的 bool 查询中 termbool 查询是兄弟关系,他们都处于外层的布尔逻辑 should 的内部,返回的命中文档至少须匹配其中一个过查询的条件。内部的 bool 查询中的两个 term 语句作为兄弟关系,同时处于 must 语句之中,所以返回的命中文档要必须都能同时匹配这两个条件。

json 复制代码
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 2.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 2.0,
        "_source" : {
          "createTime" : "2023-03-29 10:30:11",
          "tag" : "tag1",
          "price" : 10
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.9808292,
        "_source" : {
          "createTime" : "2023-03-29 10:35:11",
          "tag" : "tag2",
          "price" : 20
        }
      }
    ]
  }
}

08. ElasticSearch bool must 组合多个查询条件?

① 构造数据:

json 复制代码
PUT /my_index
{
  "mappings": {
    "properties": {
      "price":{
        "type": "integer"
      },
      "title":{
        "type": "text"
      },
      "content":{
        "type": "text"
      }
    }
  }
}

PUT /my_index/_doc/1
{
  "title": "金都时尚情侣浪漫主题酒店",
  "content": "山东省青岛市",
  "price": 300
}

PUT /my_index/_doc/2
{
  "title": "金都嘉怡假日酒店",
  "content": "北京市",
  "price": 400
}

PUT /my_index/_doc/3
{
  "title": "金都欣欣24小时酒店",
  "content": "安徽省淮北市",
  "price": 200
}

② match 查询

json 复制代码
GET  /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "嘉怡"
          }
        },
        {
          "match": {
            "content": "北京"
          }
        }
      ]
    }
  }
}
json 复制代码
{
  "took" : 18,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 3.845211,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 3.845211,
        "_source" : {
          "title" : "金都嘉怡假日酒店",
          "content" : "北京市",
          "price" : 400
        }
      }
    ]
  }
}

③ match 查询和 term 查询

json 复制代码
GET  /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "嘉怡"
          }
        },
        {
          "term": {
            "price": 400
          }
        }
      ]
    }
  }
}
json 复制代码
{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 3.1105196,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 3.1105196,
        "_source" : {
          "title" : "金都嘉怡假日酒店",
          "content" : "北京市",
          "price" : 400
        }
      }
    ]
  }
}

09. SpringBoot整合ES实现bool查询

json 复制代码
GET /my_index/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "term": {
            "tag": {
              "value": "tag1"
            }
          }
        }
      ],
      "should": [
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ],
      "must": [
        {
          "term": {
            "createTime": {
              "value": "2023-03-29 10:38:11"
            }
          }
        }
      ]
    }
  }
}
java 复制代码
@Slf4j
@Service
public class ElasticSearchImpl {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public void searchUser() throws IOException {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // bool 查询
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        // must_not
        TermQueryBuilder termQueryBuilder = new TermQueryBuilder("tag","tag1");
        boolQueryBuilder.mustNot(termQueryBuilder);

        // should
        RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("price");
        rangeQueryBuilder.gte(10);
        rangeQueryBuilder.lte(20);
        boolQueryBuilder.should(rangeQueryBuilder);

        // must
        termQueryBuilder = new TermQueryBuilder("createTime","2023-03-29 10:38:11");
        boolQueryBuilder.must(termQueryBuilder);

        searchSourceBuilder.query(boolQueryBuilder);

        SearchRequest searchRequest = new SearchRequest(new String[]{"my_index"},searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(searchResponse);
    }
}
相关推荐
IT毕设实战小研4 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
一只爱撸猫的程序猿5 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
甄超锋5 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
武昌库里写JAVA8 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习
Pitayafruit9 小时前
Spring AI 进阶之路03:集成RAG构建高效知识库
spring boot·后端·llm
zru_96029 小时前
Spring Boot 单元测试:@SpyBean 使用教程
spring boot·单元测试·log4j
甄超锋9 小时前
Java Maven更换国内源
java·开发语言·spring boot·spring·spring cloud·tomcat·maven
还是鼠鼠10 小时前
tlias智能学习辅助系统--Maven 高级-私服介绍与资源上传下载
java·spring boot·后端·spring·maven
水无痕simon14 小时前
5 索引的操作
数据库·elasticsearch
SEO_juper14 小时前
AI 搜索时代:引领变革,重塑您的 SEO 战略
人工智能·搜索引擎·seo·数字营销·seo优化