Elasticsearch查询和搜索
Elasticsearch是一个分布式、实时的搜索和分析引擎,广泛应用于全文搜索、日志分析、实时数据分析等场景。Elasticsearch提供了丰富的查询和搜索功能,如查询DSL、过滤、排序、分页、高亮和聚合等。本文将详细介绍如何在Elasticsearch中使用这些功能。
1. 查询DSL
Elasticsearch使用查询DSL(Domain Specific Language)来构建查询。查询DSL是一种基于JSON的查询语言,允许您以简洁、易读的方式构建复杂的查询。
1.1 基本查询
match
查询是一个全文搜索查询,用于在一个或多个字段中搜索文本。以下是一个match
查询示例:
{
"query": {
"match": {
"title": "Elasticsearch"
}
}
}
在此示例中,我们构建了一个match
查询,用于搜索title
字段中包含"Elasticsearch"的文档。
要在Elasticsearch中执行查询,您可以使用_search
API。以下是一个使用curl
命令执行查询的示例:
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
查询示例:
{
"query": {
"multi_match": {
"query": "Elasticsearch",
"fields": ["title", "content"]
}
}
}
在此示例中,我们构建了一个multi_match
查询,用于搜索title
和content
字段中包含"Elasticsearch"的文档。
1.1.2 Term查询
term
查询用于在一个字段中搜索精确值。以下是一个term
查询示例:
{
"query": {
"term": {
"status.keyword": "published"
}
}
}
在此示例中,我们构建了一个term
查询,用于搜索status.keyword
字段中值为"published"的文档。
1.1.3 Range查询
range
查询用于在一个字段中搜索范围内的值。以下是一个range
查询示例:
{
"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
查询允许您组合多个查询,使用逻辑运算符(如must
、should
、must_not
和filter
)来定义查询条件。以下是一个bool
查询示例:
{
"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
查询示例:
{
"query": {
"dis_max": {
"queries": [
{
"match": {
"title": "Elasticsearch"
}
},
{
"match": {
"content": "Elasticsearch"
}
}
]
}
}
}
在此示例中,我们构建了一个dis_max
查询,用于搜索title
和content
字段中包含"Elasticsearch"的文档。查询结果将根据最高得分的查询进行排序。
1.3 嵌套查询
嵌套查询用于查询包含嵌套对象的文档。假设我们有一个包含comments
嵌套对象的文档,每个评论都有一个author
和content
字段。以下是一个嵌套查询示例:
{
"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
参数。以下是一个聚合示例:
{
"query": {
"match": {
"title": "Elasticsearch"
}
},
"aggs": {
"by_category": {
"terms": {
"field": "category.keyword"
}
}
}
}
在此示例中,我们添加了一个名为by_category
的聚合,该聚合按category.keyword
字段对查询结果进行分组。terms
聚合用于计算每个类别中的文档数量。
要获取聚合结果,您可以在响应中查看aggregations
字段。以下是一个聚合结果示例:
{
...
"aggregations": {
"by_category": {
"buckets": [
{
"key": "category1",
"doc_count": 10
},
{
"key": "category2",
"doc_count": 5
}
]
}
}
}
在此示例中,我们可以看到每个类别中的文档数量。例如,category1
中有10个文档,category2
中有5个文档。
2. 过滤
2.1 过滤与查询的区别
在Elasticsearch中,查询和过滤有以下主要区别:
- 查询(Query):主要用于全文搜索,会计算文档的相关性得分(relevance