深入浅出 Elasticsearch 学习之旅 - 基础查询与数据分析

302 阅读6分钟

在这篇博客中,我们将分阶段介绍 Elasticsearch 的基础查询、复杂查询以及数据分析功能。无论你是刚刚接触 Elasticsearch,还是想更好地利用它进行数据分析,本篇博客都会是一个很好的起点。工作中可能不太常接触 Elasticsearch 的同学,也可以把它当作一个便于快速查阅的词典。

Elasticsearch 基础概念

在深入查询之前,了解一些 Elasticsearch 的基础概念是非常必要的。以下是一些核心概念,帮助你打好理解 Elasticsearch 的基础。

1. 索引(Index)

在 Elasticsearch 中,数据是通过 索引 进行组织和存储的。索引类似于传统数据库中的表,它用于存储具有相似结构的文档。每个索引可以包含多个文档,每个文档存储了多个字段。一个索引可以由多个分片(shards)组成,分布在不同的节点上。

2. 文档(Document)

Elasticsearch 中的数据存储单元是 文档,它相当于传统数据库中的一行数据。每个文档包含若干字段,每个字段可以是文本、数值、日期等类型,存储为 JSON 格式。例如,一本书的文档可以包含书名、作者、出版年份等信息。

3. 字段(Field)

文档中的数据项称为 字段。字段类似于数据库中的列,每个字段有一个类型,如 text(文本)、keyword(精确匹配)、integer(整数)等。不同字段类型的选择会影响 Elasticsearch 如何存储和索引数据。

4. 映射(Mapping)

映射类似于关系型数据库中的表结构定义。它描述了文档中各个字段的类型、分词规则等,帮助 Elasticsearch 确定如何存储和索引数据。通过定义合适的映射,可以确保数据存储高效、查询准确。

5. 集群(Cluster)与节点(Node)

Elasticsearch 是分布式的,所有节点共同构成一个 集群。一个集群由多个 节点 组成,节点是运行 Elasticsearch 的单个实例。集群通过分片将数据分布到各个节点,并通过副本提高数据冗余和查询性能。

有了这些概念,你就可以更好地理解 Elasticsearch 如何存储和管理数据了。接下来,我们将进入 Elasticsearch 的查询部分,开始学习如何进行基础查询。

第一阶段:基础查询

Elasticsearch 是一个强大的分布式搜索引擎,擅长全文搜索和数据分析。在这一阶段,我们会学习一些基本查询方法,帮助你熟悉 Elasticsearch 的核心查询功能。

1. 查询所有文档(match_all 查询)

match_all 查询是最简单的查询方式,它会返回索引中的所有文档。适用于需要检索所有数据的场景,例如对整体数据的概览。

GET /library/_search
{
  "query": {
    "match_all": {}
  }
}

解释

  • match_all 查询没有特定的条件,它会返回索引中的所有文档。适合用于检查数据是否正确导入、查看整体数据等情况。

2. 基本文本匹配(match 查询)

match 查询用于全文搜索。它会将文本字段分词,然后匹配这些词语,适用于模糊匹配场景。

GET /library/_search
{
  "query": {
    "match": {
      "title": "Elasticsearch"
    }
  }
}

解释

  • match 查询会将 title 字段的内容进行分词,然后查找包含分词结果的文档。它适合用于查找包含某个关键词的内容。
  • 在本例中,我们查找所有 title 中包含 "Elasticsearch" 的书籍。

3. 精确匹配(term 查询)

term 查询用于精确匹配未分词字段(如 keyword 类型),适合用来查找特定值,例如标签、状态。

GET /library/_search
{
  "query": {
    "term": {
      "genre.keyword": "Technology"
    }
  }
}

解释

  • term 查询用于精确匹配,适用于未分词的字段(如 keyword 类型)。
  • 在本例中,我们查找 genre 字段中等于 "Technology" 的书籍,因为 genrekeyword 类型字段,不会进行分词,适合用于精确匹配。

第二阶段:布尔查询与组合条件

在第二阶段,我们学习如何组合多个查询条件来实现更复杂的查询逻辑。布尔查询是 Elasticsearch 查询的重要工具,允许你将多个查询组合在一起。

1. 布尔查询(bool 查询)

通过 bool 查询,你可以组合 mustshouldmust_not 等条件,构建复杂的查询逻辑。

GET /library/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "Elasticsearch" } },
        { "term": { "genre.keyword": "Technology" } }
      ],
      "should": [
        { "term": { "author.keyword": "Jane Doe" } }
      ]
    }
  }
}

解释

  • must 子句表示文档必须满足的条件。在这个查询中,文档必须 title 中包含 "Elasticsearch",且 genre"Technology"
  • should 子句表示可选条件,如果满足则相关性得分更高。在这个查询中,如果 author"Jane Doe",文档的得分会更高。

2. 过滤查询(filter

filter 用于精确匹配,不参与相关性评分,且可以被缓存,适合用于需要高效处理的查询条件。

GET /library/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "Elasticsearch" } }
      ],
      "filter": [
        { "term": { "genre.keyword": "Technology" } }
      ]
    }
  }
}

解释

  • filter 子句用于精确过滤文档,不参与相关性得分计算,因此效率更高,适合需要精确匹配且不影响排序的场景。
  • 在本例中,我们查找 title 中包含 "Elasticsearch"genre"Technology" 的书籍。

第三阶段:高级查询与数据分析

在这个阶段,我们将深入学习如何使用范围查询和聚合查询来进行数据分析。

1. 范围查询(range 查询)

使用 range 查询可以查找数值或日期范围内的文档。

GET /library/_search
{
  "query": {
    "range": {
      "year": {
        "gte": 2000,
        "lte": 2020
      }
    }
  }
}

解释

  • range 查询用于查找字段值在特定范围内的文档。
  • gte(greater than or equal):表示“大于等于”。
  • lte(less than or equal):表示“小于等于”。
  • 在本例中,我们查找出版年份在 2000 到 2020 年之间的书籍。

2. 聚合查询(aggregation

聚合查询用于统计和分析数据,例如按类别分组统计数量。

GET /library/_search
{
  "size": 0,
  "aggs": {
    "books_by_genre": {
      "terms": {
        "field": "genre.keyword"
      }
    }
  }
}

解释

  • aggregation(聚合)是 Elasticsearch 中用于对数据进行分组和统计的重要工具。
  • 在本例中,terms 聚合用于统计每个 genre(类型)中有多少本书。
  • size: 0 表示我们不需要返回具体的文档,只需要返回聚合的结果。

总结

在这篇博客中,我们逐步学习了 Elasticsearch 的基础查询方法,从最简单的 match_all 查询到复杂的布尔查询和数据分析工具(如聚合查询)。这些基本的查询方法和概念为你理解和使用 Elasticsearch 打下了坚实的基础。

希望这篇博客对你有所帮助,无论是初学者还是想深入学习数据分析的开发者,掌握这些基础查询都能为你更好地利用 Elasticsearch 提供支持。如果你有任何问题,或者想要更深入了解某个部分,欢迎留言讨论!