目录
前言
Elasticsearch是一个基于Lucene的开源搜索引擎,它提供了强大的全文搜索和分析能力。在Elasticsearch中,查询是非常重要的操作,可以通过各种方式来查询数据并获取所需的结果。本文将介绍Elasticsearch中的查询操作及其常见用法。
1.目标
两个主要的概念:
Buckets(桶):满足特定条件的文档的集合
Metrics(指标):对桶内的文档进行统计计算
每个聚合都是一个或者多个桶和零个或者多个指标的组合。翻译成粗略的SQL语句来解释吧:
SELECT COUNT(field) FROM table GROUP BY field
COUNT(field) 相当于指标。GROUP BY field相当于桶。
桶在概念上类似于 SQL 的分组(GROUP BY),而指标则类似于 COUNT()、 SUM() 、 MAX() 等统计方法。
将两者结合起来——聚合
聚合是由桶和指标组成的。 聚合可能只有一个桶,可能只有一个指标,或者可能两个都有。也有可能有一些桶嵌套在其他桶里面。例如,我们可以通过所属国家来划分文档(桶),然后计算每个国家的平均薪酬(指标)。
2.查询操作
2.1.term查询
term 查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed 的字符串,term查询对于输入的文本不分析,所以它将给定的值进行精确查询。
QueryBuilders.termQuery(name,value);
POST /test_btp/_search
{
"size": 10,
"query": {
"term": {
"shopOperateType": {
"value": "1"
}
}
}
}
2.2.terms查询
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,
和 term查询一样,terms查询对于输入的文本不分析。它查询那些精确匹配的值(包括在大小写、重音、空格等方面的差异)。
QueryBuilders.termsQuery(name,value,value2,value3…);
POST /test_btp/_search
{
"size": 20,
"query": {
"terms": {
"shopOperateType": [
"0",
"1"
]
}
}
}
2.3.match_all查询
match_all查询简单的匹配所有文档。在没有指定查询方式时,它是默认的查询。
QueryBuilders.matchAllQuery();
POST /test_btp/_search
{
"size": 20,
"query": {
"match_all": {}
}
}
2.4.match查询
match查询无论你在任何字段上进行的是全文搜索还是精确查询,match 查询是你可用的标准查询。如果你在一个全文字段上使用 match查询,在执行查询前,它将用正确的分析器去分析查询字符串。如果在一个精确值的字段上使用它,例如数字、日期、布尔或者一个 not_analyzed 字符串字段,那么它将会精确匹配给定的值。
QueryBuilders.matchQuery(name, value);
POST /test_btp/_search
{
"size": 20,
"query": {
"match": {
"shopOperateType": "2"
}
}
}
2.5.multi_match查询
multi_match查询可以在多个字段上执行相同的match查询
QueryBuilders.multiMatchQuery(value, name1, name2);
POST /test_btp/_search
{
"size": 20,
"query": {
"multi_match": {
"fields":["shopOperateType","pageType"],
"query": "2"
}
}
}
2.6.range查询
range 查询找出那些落在指定区间内的数字或者时间,被允许的操作符如下:gt大于gte大于等于lt小于lte小于等于
QueryBuilders.rangeQuery(name).gte(value).lte(value);
POST /test_btp/_search
{
"size": 20,
"query": {
"range": {
"createTime": {
"gte": "1680019200000",
"lt": "1680192000000"
}
}
}
}
2.7.exists 查询和 missing查询
exists 查询和missing 查询被用于查找那些指定字段中有值 (exists) 或无值 (missing) 的文档。这与SQL中的 IS_NULL (missing) 和
NOT IS_NULL (exists) 在本质上具有共性,这些查询经常用于某个字段有值的情况和某个字段缺值的情况。
QueryBuilders.existsQuery(name);
POST /test_btp/_search
{
"size": 20,
"query": {
"exists": {
"field": "goodsId"
}
}
}
2.8.wildcard查询
模糊查询
QueryBuilders.wildcardQuery(name,+value+);
POST /test_btp/_search
{
"size": 20,
"query": {
"wildcard": {
"goodsName.keyword": "*和田*"
}
}
}
2.9.bool查询
bool组合查询,这种查询将多查询组合在一起,成为用户自己想要的布尔查询。它接收以下参数: must 文档 必须 匹配这些条件才能被包含进来。 must_not 文档 必须不 匹配这些条件才能被包含进来。 should 如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。 filter 必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
POST /test_btp/_search
{
"size": 20,
"query": {
"bool": {
"must": [
{
"term": {
"shopOperateType": {
"value": "1"
}
}
}
]
}
}
}
3.聚合查询
3.1.Value Count聚合
值聚合,主要用于统计文档总数,类似SQL的count函数。
AggregationBuilders.count("idAgg").field("id");
POST /test_btp/_search
{
"size": 0,
"aggs": {
"idAgg": {
"value_count": {
"field": "id"
}
}
}
}
3.2.Cardinality聚合
基数聚合,也是用于统计文档的总数,跟Value Count的区别是,基数聚合会去重,不会统计重复的值,类似SQL的count(DISTINCT 字段)用法。
AggregationBuilders.cardinality("goodsIdAgg").field("goodsId.keyword");
POST /test_btp/_search
{
"size": 0,
"aggs": {
"goodsIdAgg": {
"cardinality": {
"field": "goodsId.keyword"
}
}
}
}
3.3.Avg聚合
求平均值
AggregationBuilders.avg("essayBrowseTimeAgg").field("essayBrowseTime");
POST /test_btp/_search
{
"size": 0,
"aggs": {
"essayBrowseTimeAgg": {
"avg": {
"field": "essayBrowseTime"
}
}
}
}
3.4.Sum
求和计算
AggregationBuilders.sum("essayBrowseTimeAgg").field("essayBrowseTime");
POST /test_btp/_search
{
"size": 0,
"aggs": {
"essayBrowseTimeAgg": {
"sum": {
"field": "essayBrowseTime"
}
}
}
}
3.5.Max
求最大值
AggregationBuilders.max("essayBrowseTimeAgg").field("essayBrowseTime");
POST /test_btp/_search
{
"size": 0,
"aggs": {
"essayBrowseTimeAgg": {
"max": {
"field": "essayBrowseTime"
}
}
}
}
3.6.Min
求最小值
AggregationBuilders.min("essayBrowseTimeAgg").field("essayBrowseTime");
POST /test_btp/_search
{
"size": 0,
"aggs": {
"essayBrowseTimeAgg": {
"min": {
"field": "essayBrowseTime"
}
}
}
}
3.7.Terms分组聚合
terms聚合的作用跟SQL中group by作用一样,都是根据字段唯一值对数据进行分组(分桶),字段值相等的文档都分到同一个桶内。
AggregationBuilders.terms("clientTypeAgg").field("clientType.keyword");
POST /test_btp/_search
{
"size": 0,
"aggs": {
"clientTypeAgg": {
"terms": {
"field": "clientType.keyword"
}
}
}
}
3.8.Histogram分组聚合
histogram(直方图)聚合,主要根据数值间隔分组,使用histogram聚合分桶统计结果,通常用在绘制条形图报表。
AggregationBuilders.histogram("essayBrowseTimeAgg").field("essayBrowseTime").interval(5000);
POST /test_btp/_search
{
"size": 0,
"aggs": {
"essayBrowseTimeAgg": {
"histogram": {
"field": "essayBrowseTime",
"interval" : 5000 // 分桶的间隔为5000,意思就是essayBrowseTime字段值按5000间隔分组
}
}
}
}
3.9.Date histogram分组聚合
类似histogram聚合,区别是Date histogram可以很好的处理时间类型字段,主要用于根据时间、日期分桶的场景。
AggregationBuilders.dateHistogram("createTimeAgg").field("createTime").calendarInterval(DateHistogramInterval.DAY);
POST /test_btp/_search
{
"size": 0,
"aggs": {
"createTimeAgg": {
"date_histogram": {
"field": "createTime", // 根据createTime字段分组
"calendar_interval": "day" // 分组间隔:month代表每月、支持minute(每分钟)、hour(每小时)、day(每天)、week(每周)、year(每年)
}
}
}
}
3.10.Range分组聚合
range聚合,按数值范围分桶。
AggregationBuilders.range("essayBrowseTimeAgg") .field("essayBrowseTime") .addUnboundedFrom(3000) .addRange(3000, 10000) .addUnboundedTo(10000);
POST /test_btp/_search
{
"size": 0,
"aggs": {
"essayBrowseTimeAgg": { // 聚合查询名字
"range": { //聚合类型为: range
"field": "essayBrowseTime",
"ranges": [ //范围配置
{
"to": 3000 // 意思就是 essayBrowseTime <= 3000的文档归类到一个桶
},
{
"from": 3000,
"to": 10000
},
{
"from": 10000
}
]
}
}
}
}
总结
在Elasticsearch中,查询是非常重要的操作,可以通过各种查询类型来检索所需的数据。本文介绍了Elasticsearch中的基本查询、聚合查询,并给出了相应的示例。希望本文对您了解Elasticsearch查询有所帮助!