浅谈Elasticsearch查询和搜索

Elasticsearch查询和搜索

Elasticsearch是一个分布式、实时的搜索和分析引擎,广泛应用于全文搜索、日志分析、实时数据分析等场景。Elasticsearch提供了丰富的查询和搜索功能,如查询DSL、过滤、排序、分页、高亮和聚合等。本文将详细介绍如何在Elasticsearch中使用这些功能。

1. 查询DSL

Elasticsearch使用查询DSL(Domain Specific Language)来构建查询。查询DSL是一种基于JSON的查询语言,允许您以简洁、易读的方式构建复杂的查询。

1.1 基本查询

match查询是一个全文搜索查询,用于在一个或多个字段中搜索文本。以下是一个match查询示例:

json 复制代码
{
  "query": {
    "match": {
      "title": "Elasticsearch"
    }
  }
}

在此示例中,我们构建了一个match查询,用于搜索title字段中包含"Elasticsearch"的文档。

要在Elasticsearch中执行查询,您可以使用_searchAPI。以下是一个使用curl命令执行查询的示例:

bash 复制代码
curl -X GET "localhost:9200/my_index/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "title": "Elasticsearch"
    }
  }
}
'
1.1.1 Multi-match查询

multi_match查询允许您在多个字段中执行全文搜索。以下是一个multi_match查询示例:

json 复制代码
{
  "query": {
    "multi_match": {
      "query": "Elasticsearch",
      "fields": ["title", "content"]
    }
  }
}

在此示例中,我们构建了一个multi_match查询,用于搜索titlecontent字段中包含"Elasticsearch"的文档。

1.1.2 Term查询

term查询用于在一个字段中搜索精确值。以下是一个term查询示例:

json 复制代码
{
  "query": {
    "term": {
      "status.keyword": "published"
    }
  }
}

在此示例中,我们构建了一个term查询,用于搜索status.keyword字段中值为"published"的文档。

1.1.3 Range查询

range查询用于在一个字段中搜索范围内的值。以下是一个range查询示例:

json 复制代码
{
  "query": {
    "range": {
      "publish_date": {
        "gte": "2021-01-01",
        "lte": "2021-12-31"
      }
    }
  }
}

在此示例中,我们构建了一个range查询,用于搜索publish_date字段中值在"2021-01-01"到"2021-12-31"之间的文档。

1.2 复合查询

复合查询允许您组合多个查询,以构建更复杂的查询条件。

1.2.1 Bool查询

bool查询允许您组合多个查询,使用逻辑运算符(如mustshouldmust_notfilter)来定义查询条件。以下是一个bool查询示例:

json 复制代码
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "title": "Elasticsearch"
        }
      },
      "filter": {
        "range": {
          "publish_date": {
            "gte": "2021-01-01"
          }
        }
      }
    }
  }
}

在此示例中,我们构建了一个bool查询,用于搜索title字段中包含"Elasticsearch"且publish_date字段大于等于"2021-01-01"的文档。

1.2.2 Disjunction Max查询(Dis Max查询)

dis_max查询允许您在多个查询中选择最高得分的查询结果。以下是一个dis_max查询示例:

json 复制代码
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "title": "Elasticsearch"
          }
        },
        {
          "match": {
            "content": "Elasticsearch"
          }
        }
      ]
    }
  }
}

在此示例中,我们构建了一个dis_max查询,用于搜索titlecontent字段中包含"Elasticsearch"的文档。查询结果将根据最高得分的查询进行排序。

1.3 嵌套查询

嵌套查询用于查询包含嵌套对象的文档。假设我们有一个包含comments嵌套对象的文档,每个评论都有一个authorcontent字段。以下是一个嵌套查询示例:

json 复制代码
{
  "query": {
    "nested": {
      "path": "comments",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "comments.author": "John Doe"
              }
            },
            {
              "match": {
                "comments.content": "Elasticsearch"
              }
            }
          ]
        }
      }
    }
  }
}

在此示例中,我们构建了一个嵌套查询,用于搜索comments.author字段为"John Doe"且comments.content字段包含"Elasticsearch"的文档。

1.4 聚合查询

聚合查询允许您对查询结果进行分组和统计。要在查询中添加聚合,您可以使用aggs参数。以下是一个聚合示例:

json 复制代码
{
  "query": {
    "match": {
      "title": "Elasticsearch"
    }
  },
  "aggs": {
    "by_category": {
      "terms": {
        "field": "category.keyword"
      }
    }
  }
}

在此示例中,我们添加了一个名为by_category的聚合,该聚合按category.keyword字段对查询结果进行分组。terms聚合用于计算每个类别中的文档数量。

要获取聚合结果,您可以在响应中查看aggregations字段。以下是一个聚合结果示例:

json 复制代码
{
  ...
  "aggregations": {
    "by_category": {
      "buckets": [
        {
          "key": "category1",
          "doc_count": 10
        },
        {
          "key": "category2",
          "doc_count": 5
        }
      ]
    }
  }
}

在此示例中,我们可以看到每个类别中的文档数量。例如,category1中有10个文档,category2中有5个文档。

2. 过滤

2.1 过滤与查询的区别

在Elasticsearch中,查询和过滤有以下主要区别:

  • 查询(Query):主要用于全文搜索,会计算文档的相关性得分(relevance score)。
  • 过滤(Filter):主要用于精确匹配,不计算相关性得分,只返回满足条件的文档。过滤结果会被缓存,因此过滤通常比查询更快。

2.2 使用过滤

过滤允许您根据特定条件筛选查询结果。要在查询中添加过滤条件,您可以使用bool查询的filter子句。以下是一个过滤示例:

json 复制代码
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "title": "Elasticsearch"
        }
      },
      "filter": {
        "range": {
          "publish_date": {
            "gte": "2021-01-01"
          }
        }
      }
    }
  }
}

在此示例中,我们添加了一个range过滤器,用于筛选publish_date字段大于等于"2021-01-01"的文档。

2.3 常见的过滤类型

以下是一些常见的过滤类型:

2.3.1 Term过滤

term过滤用于在一个字段中搜索精确值。以下是一个term过滤示例:

json 复制代码
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "status.keyword": "published"
        }
      }
    }
  }
}

在此示例中,我们构建了一个term过滤器,用于筛选status.keyword字段中值为"published"的文档。

2.3.2 Range过滤

range过滤用于在一个字段中搜索范围内的值。以下是一个range过滤示例:

json 复制代码
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "publish_date": {
            "gte": "2021-01-01",
            "lte": "2021-12-31"
          }
        }
      }
    }
  }
}

在此示例中,我们构建了一个range过滤器,用于筛选publish_date字段中值在"2021-01-01"到"2021-12-31"之间的文档。

2.3.3 Exists过滤

exists过滤用于筛选包含特定字段的文档。以下是一个exists过滤示例:

json 复制代码
{
  "query": {
    "bool": {
      "filter": {
        "exists": {
          "field": "author"
        }
      }
    }
  }
}

在此示例中,我们构建了一个exists过滤器,用于筛选包含author字段的文档。

2.3.4 Bool过滤

bool过滤允许您组合多个过滤条件,使用逻辑运算符(如mustshouldmust_not)来定义过滤条件。以下是一个bool过滤示例:

json 复制代码
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "status.keyword": "published"
          }
        },
        {
          "range": {
            "publish_date": {
              "gte": "2021-01-01"
            }
          }
        }
      ]
    }
  }
}

在此示例中,我们构建了一个bool过滤器,用于筛选status.keyword字段中值为"published"且publish_date字段大于等于"2021-01-01"的文档。

2.3.5 Geo距离过滤

geo_distance过滤用于筛选距离给定地理坐标一定范围内的文档。以下是一个geo_distance过滤示例:

json 复制代码
{
  "query": {
    "bool": {
      "filter": {
        "geo_distance": {
          "distance": "100km",
          "location": {
            "lat": 40.7128,
            "lon": -74.0060
          }
        }
      }
    }
  }
}

在此示例中,我们构建了一个geo_distance过滤器,用于筛选距离纬度40.7128、经度-74.0060的地理坐标100公里以内的文档。

2.4 组合查询和过滤

在实际应用中,您可能需要根据多个条件对文档进行查询和过滤。以下是一个组合查询和过滤的示例:

json 复制代码
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "title": "Elasticsearch"
        }
      },
      "filter": [
        {
          "term": {
            "status.keyword": "published"
          }
        },
        {
          "range": {
            "publish_date": {
              "gte": "2021-01-01"
            }
          }
        }
      ]
    }
  }
}

在此示例中,我们构建了一个bool查询,用于搜索title字段中包含"Elasticsearch"的文档。同时,我们添加了两个过滤器,用于筛选status.keyword字段中值为"published"且publish_date字段大于等于"2021-01-01"的文档。

3. 排序

3.1 基本排序

在 Elasticsearch 中,我们可以使用 _sort 参数来指定排序字段。例如,我们有一个名为 products 的索引,其中包含了一些商品信息,我们可以根据商品的价格(price)进行升序排序:

json 复制代码
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    }
  ]
}

在这个例子中,我们使用了 match_all 查询来获取所有的商品,然后通过 sort 参数指定了按照 price 字段进行升序排序。order 参数可以接受 asc(升序)和 desc(降序)两个值。

3.2 多字段排序

有时候,我们需要根据多个字段进行排序。在 Elasticsearch 中,我们可以在 sort 参数中指定多个排序字段。例如,我们可以先根据商品的价格进行升序排序,然后再根据商品的评分(rating)进行降序排序:

json 复制代码
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    },
    {
      "rating": {
        "order": "desc"
      }
    }
  ]
}

在这个例子中,我们在 sort 参数中指定了两个排序字段,分别是 pricerating。Elasticsearch 会先根据 price 进行排序,然后再根据 rating 进行排序。

3.3 按照距离排序

Elasticsearch 支持按照地理位置进行排序。例如,我们有一个名为 shops 的索引,其中包含了一些商店的信息,我们可以根据商店的位置(location)和用户的位置进行排序:

json 复制代码
GET /shops/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 40.715,
          "lon": -73.988
        },
        "order": "asc",
        "unit": "km"
      }
    }
  ]
}

在这个例子中,我们使用了 _geo_distance 排序,它会根据商店的位置(location)和用户的位置(经纬度)计算距离,并按照距离进行排序。order 参数用于指定排序方式,unit 参数用于指定距离的单位。

3.4 按照评分排序

在 Elasticsearch 中,我们可以使用 _score 参数来按照文档的评分进行排序。例如,我们可以根据商品的名称(name)进行搜索,并按照评分进行降序排序:

json 复制代码
GET /products/_search
{
  "query": {
    "match": {
      "name": "iphone"
    }
  },
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    }
  ]
}

在这个例子中,我们使用了 match 查询来搜索商品名称中包含 iphone 的商品,然后通过 sort 参数指定了按照评分进行降序排序。

3.5 自定义排序

Elasticsearch 支持使用脚本(Script)来自定义排序。例如,我们可以根据商品的价格(price)和销量(sales)计算一个综合得分,并按照综合得分进行排序:

json 复制代码
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "_script": {
        "type": "number",
        "script": {
          "source": "doc['price'].value * 0.8 + doc['sales'].value * 0.2"
        },
        "order": "desc"
      }
    }
  ]
}

在这个例子中,我们使用了 _script 排序,它允许我们使用脚本来计算一个自定义的排序值。在这里,我们使用了一个简单的公式 doc['price'].value * 0.8 + doc['sales'].value * 0.2 来计算综合得分,其中 price 占 80%,sales 占 20%。然后我们通过 order 参数指定了按照综合得分进行降序排序。

需要注意的是,使用脚本排序可能会影响查询性能,因此在实际应用中需要权衡性能和灵活性。

3.6 排序缺失值处理

在 Elasticsearch 中,如果排序字段中存在缺失值,我们可以使用 missing 参数来指定如何处理这些缺失值。例如,我们可以将缺失的价格(price)视为最低价格:

json 复制代码
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "asc",
        "missing": "_first"
      }
    }
  ]
}

在这个例子中,我们使用了 missing 参数,并将其设置为 _first,这意味着缺失值将被视为最小值,因此在升序排序时,它们将排在最前面。我们还可以将 missing 设置为 _last(将缺失值视为最大值)或者一个具体的数值。

4. 分页

4.1 基本分页

在 Elasticsearch 中,我们可以使用 fromsize 参数来实现分页。from 参数表示起始文档的位置(从 0 开始),size 参数表示每页文档的数量。例如,我们有一个名为 products 的索引,其中包含了一些商品信息,我们可以获取第一页的商品(每页 10 个):

json 复制代码
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 10
}

在这个例子中,我们使用了 match_all 查询来获取所有的商品,然后通过 fromsize 参数指定了分页信息。这里 from 为 0,表示从第一个文档开始,size 为 10,表示每页包含 10 个文档。

4.2 深度分页

在 Elasticsearch 中,我们可以通过调整 from 参数的值来实现深度分页。例如,我们可以获取第二页的商品(每页 10 个):

json 复制代码
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "from": 10,
  "size": 10
}

在这个例子中,我们将 from 参数的值设置为 10,表示从第 11 个文档开始。其他参数保持不变。

需要注意的是,深度分页可能会影响查询性能。因为 Elasticsearch 需要跳过 from 参数指定的文档数量,这可能会导致较高的内存和 CPU 消耗。在实际应用中,我们应该尽量避免使用过大的 from 值。

4.3 分页限制

Elasticsearch 默认允许查询的最大文档数量为 10000。这意味着,如果我们使用 fromsize 参数进行分页,from + size 的值不能超过 10000。例如,以下查询将会失败:

json 复制代码
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "from": 9900,
  "size": 200
}

在这个例子中,from + size 的值为 10100,超过了默认的最大文档数量。为了解决这个问题,我们可以使用 index.max_result_window 参数来调整最大文档数量。例如,我们可以将其设置为 20000:

json 复制代码
PUT /products/_settings
{
  "index": {
    "max_result_window": 20000
  }
}

需要注意的是,增加最大文档数量可能会导致更高的内存和 CPU 消耗。在实际应用中,我们应该根据需求和资源情况来调整这个参数。

4.4 搜索结果遍历

对于大量数据的遍历,我们可以使用 Elasticsearch 的 Scroll API。Scroll API 可以在一定时间内保留查询快照,从而避免深度分页带来的性能问题。以下是一个使用 Scroll API 的例子:

json 复制代码
# 初始化 scroll
GET /products/_search?scroll=1m
{
  "query": {
    "match_all": {}
  },
  "size": 10
}

```json
# 使用 scroll_id 获取下一页结果
GET /_search/scroll
{
  "scroll": "1m",
  "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndU..."
}

在这个例子中,我们首先使用 scroll 参数初始化了一个 scroll 上下文,并设置了一个 1 分钟的保留时间。然后,我们使用 size 参数指定每次获取 10 个文档。在获取下一页结果时,我们需要使用上一次查询返回的 scroll_id。这个过程可以重复进行,直到所有文档都被遍历完。

需要注意的是,当遍历完成后,我们应该及时清除 scroll 上下文,以释放资源:

json 复制代码
DELETE /_search/scroll
{
  "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndU..."
}

4.5 分页与排序

在使用 Elasticsearch 进行分页时,我们通常需要对查询结果进行排序。例如,我们可以根据商品的价格(price)进行升序排序,并获取第一页的商品(每页 10 个):

json 复制代码
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    }
  ],
  "from": 0,
  "size": 10
}

在这个例子中,我们使用了 sort 参数来指定排序字段,并通过 fromsize 参数指定了分页信息。这样,我们可以获取按照价格排序的商品列表,并进行分页展示。

5. 高亮

5.1 基本高亮

在 Elasticsearch 中,我们可以使用 highlight 参数来实现高亮。例如,我们有一个名为 articles 的索引,其中包含了一些文章信息,我们可以根据文章的标题(title)和内容(content)进行搜索,并高亮匹配的关键词:

json 复制代码
GET /articles/_search
{
  "query": {
    "multi_match": {
      "query": "Elasticsearch",
      "fields": ["title", "content"]
    }
  },
  "highlight": {
    "fields": {
      "title": {},
      "content": {}
    }
  }
}

在这个例子中,我们使用了 multi_match 查询来搜索标题和内容中包含 "Elasticsearch" 的文章,然后通过 highlight 参数指定了高亮字段。这里我们指定了 titlecontent 两个字段进行高亮。

查询结果中,每个文档都会包含一个 highlight 字段,其中包含了高亮后的文本片段。默认情况下,高亮的关键词会被包裹在 <em> 标签中。

5.2 高亮标签

在 Elasticsearch 中,我们可以自定义高亮标签。例如,我们可以将高亮关键词包裹在 <strong> 标签中:

json 复制代码
GET /articles/_search
{
  "query": {
    "multi_match": {
      "query": "Elasticsearch",
      "fields": ["title", "content"]
    }
  },
  "highlight": {
    "pre_tags": ["<strong>"],
    "post_tags": ["</strong>"],
    "fields": {
      "title": {},
      "content": {}
    }
  }
}

在这个例子中,我们使用了 pre_tagspost_tags 参数来指定高亮标签。这里我们将高亮关键词包裹在 <strong> 标签中。

5.3 高亮片段

在 Elasticsearch 中,我们可以控制高亮片段的数量和长度。例如,我们可以设置每个字段最多返回 3 个高亮片段,每个片段最多包含 150 个字符:

json 复制代码
GET /articles/_search
{
  "query": {
    "multi_match": {
      "query": "Elasticsearch",
      "fields": ["title", "content"]
    }
  },
  "highlight": {
    "number_of_fragments": 3,
    "fragment_size": 150,
    "fields": {
      "title": {},
      "content": {}
    }
  }
}

在这个例子中,我们使用了 number_of_fragmentsfragment_size 参数来控制高亮片段。这里我们设置了每个字段最多返回 3 个高亮片段,每个片段最多包含 150 个字符。

5.4 高亮类型

Elasticsearch 支持多种高亮类型,包括 plain(默认)、postingsfvh。不同的高亮类型在性能和功能上有所差异。例如,我们可以使用 postings 高亮类型来提高高亮性能:

json 复制代码
GET /articles/_search
{
  "query": {
    "multi_match": {
      "query": "Elasticsearch",
      "fields": ["title", "content"]
    }
  },
  "highlight": {
    "type": "postings",
    "fields": {
      "title": {},
      "content": {}
    }
  }
}

在这个例子中,我们使用了 type 参数来指定高亮类型。这里我们将高亮类型设置为 postings。需要注意的是,使用 postings 高亮类型时,我们需要在索引设置中启用 term_vector

json 复制代码
PUT /articles
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "term_vector": "with_positions_offsets"
      },
      "content": {
        "type": "text",
        "term_vector": "with_positions_offsets"
      }
    }
  }
}

在这个例子中,我们在创建索引时为 titlecontent 字段启用了 term_vector。这样,我们就可以使用 postings 高亮类型来提高高亮性能。

5.5 高亮查询

在某些情况下,我们可能需要根据不同的查询条件来高亮文本。Elasticsearch 支持使用 highlight_query 参数来指定高亮查询。例如,我们可以根据文章的标题(title)和内容(content)进行搜索,但只高亮标题中的关键词:

json 复制代码
GET /articles/_search
{
  "query": {
    "multi_match": {
      "query": "Elasticsearch",
      "fields": ["title", "content"]
    }
  },
  "highlight": {
    "fields": {
      "title": {
        "highlight_query": {
          "match": {
            "title": "Elasticsearch"
          }
        }
      }
    }
  }
}

在这个例子中,我们使用了 highlight_query 参数来指定高亮查询。这里我们设置了只高亮标题中的关键词。

6. 聚合

6.1 基本聚合

在 Elasticsearch 中,我们可以使用 aggs 参数来实现聚合。例如,我们有一个名为 sales 的索引,其中包含了一些销售记录,我们可以根据商品类别(category)进行分组,并计算每个类别的销售总额(amount):

json 复制代码
GET /sales/_search
{
  "size": 0,
  "aggs": {
    "category_stats": {
      "terms": {
        "field": "category.keyword"
      },
      "aggs": {
        "total_amount": {
          "sum": {
            "field": "amount"
          }
        }
      }
    }
  }
}

在这个例子中,我们使用了 terms 聚合来根据商品类别进行分组,然后使用了 sum 聚合来计算每个类别的销售总额。这里我们将聚合结果命名为 category_stats

查询结果中,会包含一个名为 aggregations 的字段,其中包含了聚合结果。在这个例子中,我们可以获取每个类别的销售总额。

6.2 按照范围聚合

在 Elasticsearch 中,我们可以使用 range 聚合来根据指定的范围进行分组。例如,我们可以根据销售额(amount)的范围进行分组,统计不同范围内的销售记录数量:

json 复制代码
GET /sales/_search
{
  "size": 0,
  "aggs": {
    "amount_ranges": {
      "range": {
        "field": "amount",
        "ranges": [
          { "to": 100 },
          { "from": 100, "to": 500 },
          { "from": 500 }
        ]
      }
    }
  }
}

在这个例子中,我们使用了 range 聚合来根据销售额的范围进行分组。这里我们定义了三个范围:小于 100、100 到 500、大于 500。查询结果中,我们可以获取不同范围内的销售记录数量。

6.3 日期聚合

在 Elasticsearch 中,我们可以使用 date_histogram 聚合来根据日期进行分组。例如,我们可以根据销售日期(date)进行分组,统计每个月的销售总额(amount):

json 复制代码
GET /sales/_search
{
  "size": 0,
  "aggs": {
    "monthly_sales": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "total_amount": {
          "sum": {
            "field": "amount"
          }
        }
      }
    }
  }
}

在这个例子中,我们使用了 date_histogram 聚合来根据销售日期进行分组。这里我们设置了 calendar_interval 参数为 month,表示按照月份进行分组。查询结果中,我们可以获取每个月的销售总额。

6.4 嵌套聚合

在 Elasticsearch 中,我们可以使用嵌套聚合来实现多层分组。例如,我们可以先根据商品类别(category)进行分组,然后再根据销售员(salesperson)进行分组,统计每个类别下每个销售员的销售总额(amount):

json 复制代码
GET /sales/_search
{
  "size": 0,
  "aggs": {
    "category_stats": {
      "terms": {
        "field": "category.keyword"
      },
      "aggs": {
        "salesperson_stats": {
          "terms": {
            "field": "salesperson.keyword"
          },
          "aggs": {
            "total_amount": {
              "sum": {
                "field": "amount"
              }
            }
          }
        }
      }
    }
  }
}

在这个例子中,我们首先使用了 terms 聚合来根据商品类别进行分组,然后在每个类别下再使用 terms 聚合根据销售员进行分组。最后,我们使用了 sum 聚合来计算每个类别下每个销售员的销售总额。查询结果中,我们可以获取多层分组的统计信息。

6.5 按照过滤条件聚合

在 Elasticsearch 中,我们可以使用 filter 聚合来根据过滤条件进行分组。例如,我们可以根据销售员(salesperson)为 "Alice" 的条件进行过滤,统计满足条件的销售总额(amount):

json 复制代码
GET /sales/_search
{
  "size": 0,
  "aggs": {
    "alice_sales": {
      "filter": {
        "term": {
          "salesperson.keyword": "Alice"
        }
      },
      "aggs": {
        "total_amount": {
          "sum": {
            "field": "amount"
          }
        }
      }
    }
  }
}

在这个例子中,我们使用了 filter 聚合来根据销售员为 "Alice" 的条件进行过滤。然后我们使用了 sum 聚合来计算满足条件的销售总额。查询结果中,我们可以获取 "Alice" 的销售总额。

总结

本文详细介绍了Elasticsearch的查询和搜索功能,包括查询DSL、过滤、排序、分页、高亮和聚合等。通过使用这些功能,您可以构建复杂的查询和分析,以满足各种业务场景和需求。希望本文能为您提供有关如何在Elasticsearch中使用查询和搜索功能的有用信息。

相关推荐
落雪财神意2 分钟前
黄金本周想法
大数据·人工智能·金融·区块链·期股
TDengine (老段)11 分钟前
TDengine 数学函数 PI 用户手册
大数据·数据库·时序数据库·iot·tdengine·涛思数据
lang2015092812 分钟前
Spring Boot Actuator应用信息Application Information全解析
spring boot·后端·elasticsearch
三口吃掉你8 小时前
Docker安装Elasticsearch、kibana、IK分词器
elasticsearch·docker·kibana·ik分词器
dehuisun9 小时前
jenkins流水线部署springboot项目
运维·jenkins
神秘人X70712 小时前
Jenkins 持续集成与部署指南
运维·ci/cd·jenkins
呆呆小金人12 小时前
SQL入门:正则表达式-高效文本匹配全攻略
大数据·数据库·数据仓库·sql·数据库开发·etl·etl工程师
一棵树735113 小时前
Android OpenGL ES初窥
android·大数据·elasticsearch
_李小白13 小时前
【OPENGL ES 3.0 学习笔记】第九天:缓存、顶点和顶点数组
笔记·学习·elasticsearch
白鲸开源13 小时前
(二)从分层架构到数据湖仓架构:数据仓库分层下的技术架构与举例
大数据·数据库·数据分析