顿搜
02. ES精准匹配查询——ElasticSearch搜索专栏
一、term查询
term查询是结构化精准查询的主要查询方式,用于查询待查字段和查询值是否完全匹配
1.1 DSL方式
GET /${index_name}/_search
{
"query": {
"term": {
"${FIELD}": { //搜索字段名称
"value": "${ VALUE }" //搜索值
}
}
}
}FIELD的数据类型可以是数值型、布尔型、日期型、数组型及关键字等。
1.2 Java 客户端方式
在Java客户端中进行查询时,可以调用QueryBuilders.termQuery()方法新建一个term查询。
termQuery()方法传入不同的参数即可生成不同数据类型的term查询,
可以传入boolean、double、float、int、long和String等类型的参数,
但是没有日期类型的参数,可以使用日期形式字符串类型的term查询来解决。
以下为使用日期类型的字符串参数构建的term查询
public void termDateSearch() {
//创建搜索请求
SearchRequest searchRequest = new SearchRequest("hotel");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建term查询
searchSourceBuilder.query(QueryBuilders.termQuery("create_time", "20210509160000"));
searchRequest.source(searchSourceBuilder); //设置查询请求
printResult(searchRequest); //打印搜索结果
}二、terms查询
terms查询是term查询的扩展形式,用于查询一个或多个值与待查字段是否完全匹配
2.1 DSL方式
GET /${index_name}/_search
{
"query": {
"terms": {
"FIELD": [ //指定查询字段
"VALUE1", //指定查询值,多个值之间用逗号分隔
"VALUE2",
…
]
}
}
}FIELD的数据类型可以是数值型、布尔型、日期型、数组型及关键字等。
terms中的词,是或的关系,任意一个满足即可
2.2 Java 客户端方式
在Java客户端中对应terms查询的类为TermsQuery,该类的实例通过QueryBuilders.termsQuery()生成。
在QueryBuilders.termsQuery()方法中,第一个参数为字段名称,
第二个参数可以是一个集合类型,也可以是一个单独类型,当为单独类型时,该参数为可变长度参数。
public void termsSearch() {
//创建搜索请求
SearchRequest searchRequest = new SearchRequest("hotel");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建terms查询
searchSourceBuilder.query(QueryBuilders.termsQuery("city","北京","天津"));
searchRequest.source(searchSourceBuilder); //设置查询请求
printResult(searchRequest); //打印搜索结果
}三、range查询
range查询用于范围查询,一般是对数值型和日期型数据的查询。
使用range进行范围查询时,用户可以按照需求中是否包含边界数值进行选项设置,可供组合的选项如下
- gt:大于
- lt:小于
- gte:大于或等于
- lte:小于或等于
3.1 DSL方式
GET /hotel/_search
{
"query": {
"range": { //range查询
"price": { //指定字段为price,此处包含边界值
"gte": 300,
"lte": 500
}
}
}
}使用range查询时,查询值必须符合该字段在mappings中设置的规范。
例如,price字段是double类型,则range应该使用数值型或者数值类型的字符串形式,不能使用其他形式
3.2 Java 客户端方式
在Java客户端上构建range请求是使用QueryBuilders.rangeQuery()方法实现的,
该方法的参数为字段名称,然后再调用相应的方法即可构建相应的查询范围。
可以调用gt()、lt()、gte()和lte()等方法分别实现大于、小于、大于等于、小于等于等查询范围。
在使用时,可以直接连着使用“.”操作符,这样不用拆分语句,也比较容易理解。
public void rangeSearch() {
//创建搜索请求
SearchRequest searchRequest = new SearchRequest("hotel");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建range查询
QueryBuilder queryBuilder = QueryBuilders.rangeQuery("create_time")
.gte("20210115120000").lte("20210116120000");
searchSourceBuilder.query(queryBuilder);
searchRequest.source(searchSourceBuilder); //设置查询请求
printResult(searchRequest); //打印搜索结果
}四、exists查询
在某些场景下,我们希望找到某个字段不为空的文档,则可以用exists搜索。
字段不为空的条件有:
- 值存在且不是null;
- 值不是空数组;
- 值是数组,但不是[null]。
4.1 DSL方式
GET /dbindex/_search
{
"query": {
"exists": { //查询tag字段不为空的文档
"field": "tag"
}
}
}4.2 Java 客户端方式
在Java客户端上构建exists查询时,使用QueryBuilders.existsQuery(String name)来构建,
传递的name参数是目标字段名称。
public void existsSearch(){
SearchRequest searchRequest=new SearchRequest("hotel_1");
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.existsQuery("tag"));
searchRequest.source(searchSourceBuilder);
printResult(searchRequest);
}五、ids查询
ids就是通过id进行批量查询
5.1 DSL方式
GET /dbindex/_search
{
"query": {
"ids":
{
"values": [1,3]
}
}
}返回结果的顺序和我们查找时设置的顺序没有任何关系
六、prefix查询
使用prefix可以根据前缀来查找某个字段
6.1 DSL方式
GET /dbindex/_search
{
"query": {
"prefix": {
"name": {
"value": "张"
}
}
}
}七、terms_set查询
使用terms_set关键字查询可以统计文档中动态匹配到单词的个数
7.1 DSL方式
GET /dbindex/_search
{
"query": {
"terms_set": {
"programming_languages": {
"terms": [ "dotnet", "php"],
"minimum_should_match_field": "required_matches"
}
}
}
}