ElasticSearch高级查询

本文介绍了Elasticsearch中的布尔查询和聚合查询方法,详细解释了Bool查询的四种子句:must、filter、should和must_not,以及如何利用这些子句进行高效的过滤和组合查询。此外,还探讨了如何通过聚合查询实现类似关系型数据库中的最大值、最小值、平均值等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章内容概述

1、布尔查询
2、聚合查询

1、布尔查询Bool Query

	Elasticsearch在2.x版本的时候把filter查询给摘掉了,因此在query dsl里面已经找不到filter query了。其实es并没有完全抛弃
filter query,而是它的设计与之前的query太重复了。因此直接给转移到了bool查询中。

	Bool查询现在包括四种子句,must,filter,should,must_not。

1.1 为什么filter会快?

在这里插入图片描述

	看上面的流程图就能很明显的看到,filter与query还是有很大的区别的。

	比如,query的时候,会先比较查询条件,然后计算分值,最后返回文档结果;

	而filter则是先判断是否满足查询条件,如果不满足,会缓存查询过程(记录该文档不满足结果);满足的话,就直接缓存结果。

	综上所述,filter快在两个方面:

	1 对结果进行缓存
	2 避免计算分值

1.2 bool查询的使用

	Bool查询对应Lucene中的BooleanQuery,它由一个或者多个子句组成,每个子句都有特定的类型。

	must:返回的文档必须满足must子句的条件,并且参与计算分值

	filter:返回的文档必须满足filter子句的条件。但是不会像Must一样,参与计算分值

	should:返回的文档可能满足should子句的条件。在一个Bool查询中,如果没有must或者filter,有一个或者多个should子句,那么
只要满足一个就可以返回。minimum_should_match参数定义了至少满足几个子句。

	must_nout:返回的文档必须不满足must_not定义的条件。
	
	更多内容请参考:https://www.cnblogs.com/xing901022/p/5994210.html

1.2.1 数据准备

批量添加数据:
POST /lib4/items/_bulk
{"index":{"_id":1}}
{"price":40,"itemID":"ID100123"}
{"index":{"_id":2}}
{"price":50,"itemID":"ID100124"}
{"index":{"_id":3}}
{"price":25,"itemID":"ID100125"}
{"index":{"_id":4}}
{"price":30,"itemID":"ID100126"}
{"index":{"_id":5}}
{"price":null,"itemID":"ID100127"}

1.2.2 filter查询

1、查询价格为40的商品
### 过滤price是40的商品
GET /lib4/items/_search
{
  "query": {
    "bool": {
      "filter": [
          {"term":{"price":40}}
        ]
    }
  }
}
2、查询价格为25或40的商品
GET /lib4/items/_search
{
  "query": {
    "bool": {
      "filter": [
          {"terms":{"price":[25,40]}}
        ]
    }
  }
}
3、查询商品编号为ID100123的商品
GET /lib4/items/_search
{
  "query": {
    "bool": {
      "filter": [
          {"term":{"itemID":"ID100123"}}
        ]
    }
  }
}
	结果发现,什么都没有查到,原因在于我们使用的是动态映射,分词器会把ID100123进行分词,ID转换为小写的id,我们只需要把ID改为小
写即可。
	当然,我们也可以使用静态映射来定义;
PUT /lib4
{
  "mappings": {
    "items":{
      "properties":{
        "itemID":{
          "type":"text",
          "index":false
        }
      }
    }
  }
}

略
4、过滤商品价格为25-50之间的商品

	gt		相当于	>
	lt		相当于 <
	gte		相当于 >=
	lte		相当于	<=
GET /lib4/items/_search
{
  "query": {
    "bool": {
      "filter":{
          "range":{
            "price":{
              "gt":25,
              "lt":50
            }
          }
      }
    }
  }
}
5、过滤价格不为空的商品
GET /lib4/items/_search
{
  "query": {
    "bool": {
      "filter":{
          "exists": {
            "field": "price"
          }
      }
    }
  }
}

1.2.3 bool查询查询

可以实现组合过滤查询

格式:
	"bool": {
	  "must": [
		{}
	  ],
	  "should": [
		{}
	  ],
	  "must_not": [
		{}
	  ]
	}

	must:必须满足的条件	--->and
	shouid:可以满足也可以不满足的条件		--->or
	must_not:不需要满足的条件		--->not

1、查询价格是25或商品id为id100123,但是价格不能是40的
GET /lib4/items/_search
{
  "query": {
    "bool": {
      "should": [
        {"term": {
          "price": {
            "value": 25
          }
        }},
        {
          "term": {
            "itemID": {
              "value": "id100123"
            }
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "price": {
              "value": 40
            }
          }
        }
      ]
    }
  }
}
2、查询商品编号是id100123的 或者 必须同时满足商品编号是100124和价格为40的
GET /lib4/items/_search
{
  "query": {
    "bool": {
      "should": [
        {"term":{"itemID": "id100123"}},
        {
          "bool": {
            "must": [
              {"term":{"itemID": "id100123"}},
              {"term":{"price": 40}}
            ]
          }
        }
      ]
    }
  }
}

2、聚合查询

类似于关系型数据库的最大值、最小值、平均值、求和等

语法规则:
	GET /索引名/类型/_search
	{
		"aggs":{
			"聚合结果变量名":{
				"sum/max/min/avg等":{
					"field":"指定字段"
				}
			}
		}
	}
	
	"aggs"		用来定义聚合查询

1、查询所有商品的总价格
GET /lib4/items/_search
{
	"aggs":{
		"price_of_sum":{
			"sum":{
				"field":"price"
			}
		}
	}
}
我们会发现,查询出来的结果里面参照了很多商品数据
结果:
{
  "took": 66,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 5,
    "max_score": 1,
    "hits": [
      {
        "_index": "lib4",
        "_type": "items",
        "_id": "5",
        "_score": 1,
        "_source": {
          "price": null,
          "itemID": "ID100127"
        }
      },
      {
        "_index": "lib4",
        "_type": "items",
        "_id": "2",
        "_score": 1,
        "_source": {
          "price": 50,
          "itemID": "ID100124"
        }
      },
      {
        "_index": "lib4",
        "_type": "items",
        "_id": "4",
        "_score": 1,
        "_source": {
          "price": 30,
          "itemID": "ID100126"
        }
      },
      {
        "_index": "lib4",
        "_type": "items",
        "_id": "1",
        "_score": 1,
        "_source": {
          "price": 40,
          "itemID": "ID100123"
        }
      },
      {
        "_index": "lib4",
        "_type": "items",
        "_id": "3",
        "_score": 1,
        "_source": {
          "price": 25,
          "itemID": "ID100125"
        }
      }
    ]
  },
  "aggregations": {
    "price_of_sum": {
      "value": 145
    }
  }
}
我们如果为了精简看结果,可以通过size来改变现实数量:
GET /lib4/items/_search
{
  "size": 0, 
	"aggs":{
		"price_of_sum":{
			"sum":{
				"field":"price"
			}
		}
	}
}
2、查询价格最低的商品
GET /lib4/items/_search
{
  "size": 0, 
	"aggs":{
		"price_of_min":{
			"min":{
				"field":"price"
			}
		}
	}
}
3、查询价格最高的商品
GET /lib4/items/_search
{
  "size": 0, 
	"aggs":{
		"price_of_max":{
			"max":{
				"field":"price"
			}
		}
	}
}
4、查询所有商品的平均价格
GET /lib4/items/_search
{
  "size": 0, 
	"aggs":{
		"price_of_avg":{
			"avg":{
				"field":"price"
			}
		}
	}
}
5、求价格的基数:基数指的是所有价格不同的数量
GET /lib4/items/_search
{
  "size": 0, 
	"aggs":{
		"price_of_cardinality":{
			"cardinality":{
				"field":"price"
			}
		}
	}
}
6、根据价格分组查询:价格相同的一组
POST /lib4/items/_bulk
{"index":{"_id":6}}
{"price":30,"itemID":"ID100127"}


GET /lib4/items/_search
{
  "size": 0, 
	"aggs":{
		"price_of_group":{
			"terms":{
				"field":"price"
			}
		}
	}
}
7、综合练习:对那些有唱歌兴趣的用户按年龄分组[使用之前的user]
GET /lib3/user/_search
{
  "query": {
    "match": {
      "interests": "唱歌"
    }
  },
  "aggs": {
    "age_of_group": {
      "terms": {
        "field": "age"
      }
    }
  }
}
8、综合练习:对那些有唱歌兴趣的用户按年龄分组,分组之后求每一组的平均年龄
GET /lib3/user/_search
{
  "query": {
    "match": {
      "interests": "唱歌"
    }
  },
  "aggs": {
    "age_of_group": {
      "terms": {
        "field": "age"
      },
      "aggs": {
        "age_of_avg": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  }
}

“aggs”: {
“age_of_group”: {
“terms”: {
“field”: “age”
}
}
}
}

	8、综合练习:对那些有唱歌兴趣的用户按年龄分组,分组之后求每一组的平均年龄

GET /lib3/user/_search
{
“query”: {
“match”: {
“interests”: “唱歌”
}
},
“aggs”: {
“age_of_group”: {
“terms”: {
“field”: “age”
},
“aggs”: {
“age_of_avg”: {
“avg”: {
“field”: “age”
}
}
}
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JTZ001

你的鼓励是我创作的最大动力?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值