Elasticsearch入门教程-索引、搜索与分析详解

Elasticsearch 入门教程 - 索引、搜索与分析详解

Elasticsearch 是一个基于 Lucene 的开源搜索引擎,它提供了一个分布式、多租户能力的全文搜索引擎,具有 HTTP Web 接口和无模式 JSON 文档。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

本文将带领您深入了解 Elasticsearch 的核心概念:索引、搜索和分析,并通过具体的示例帮助您快速上手。

一、 索引:数据的基石

在 Elasticsearch 中,索引(Index)类似于关系型数据库中的数据库,它是存储相关文档的地方。索引实际上是指向一个或者多个物理分片的逻辑命名空间。

1.1 索引的概念

  • 名词: 一个索引类似于传统关系数据库中的一个数据库,是一个存储关系型文档的地方。
  • 动词: 索引一个文档就是存储一个文档到一个索引(名词)中以便它可以被检索和查询到。这非常类似于 SQL 语句中的 INSERT 关键词,除了文档已存在时,新文档会替换旧文档,也就是修改操作。

1.2 分片与副本

一个分片是一个底层的工作单元,它仅保存了全部数据中的一部分。在 Elasticsearch 中,每个分片本身也是一个功能完善且独立的“索引”,可以被放置到集群中的任何节点上。

  • 分片 (Shards):

    • 将索引分成多个分片,将数据分散存储到多个节点上,解决单个节点数据量过大的问题。
    • 分片是 Elasticsearch 最小的存储单元,每个分片都是一个独立的 Lucene 索引。
    • 分片数量在创建索引时指定,创建后不可更改。
  • 副本 (Replicas):

    • 复制分片,每个主分片可以有多个副本分片。
    • 提供数据冗余,防止数据丢失。当一个节点发生故障时,可以从副本分片中读取数据。
    • 提高查询性能,可以将查询请求分发到多个副本分片上,实现负载均衡。
    • 副本数量可以在创建索引后动态调整。

分片和副本的引入使得 Elasticsearch 具备了高可用性和可扩展性。

1.3 映射 (Mapping)

映射定义了索引中的文档结构,包括字段名称、字段数据类型、字段使用的分词器等。

  • 动态映射 (Dynamic Mapping): Elasticsearch 可以根据插入的文档自动推断字段类型并创建映射,这就是动态映射。
  • 静态映射 (Explicit Mapping): 用户可以自定义映射,例如指定字段类型、设置分词器等,以更精确地控制索引的行为。

示例: 创建一个名为 products 的索引,包含 name, description, price, 和 category 字段。

json
PUT /products
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "standard"
},
"description": {
"type": "text",
"analyzer": "standard"
},
"price": {
"type": "double"
},
"category": {
"type": "keyword"
}
}
}
}

代码解释:

  • PUT /products: 创建一个名为 products 的索引。
  • settings: 索引级别的设置。
    • number_of_shards: 设置主分片数量为 3。
    • number_of_replicas: 设置每个主分片的副本数量为 2。
  • mappings: 定义索引的映射。
    • properties: 定义字段及其属性。
      • name, description: text 类型,可以进行全文搜索,使用标准分词器 standard
      • price: double 类型,存储双精度浮点数。
      • category: keyword 类型,表示精确值,不进行分词。

二、 搜索:检索的力量

Elasticsearch 强大的搜索能力是其核心优势之一。它支持各种类型的查询,可以满足各种复杂的搜索需求。

2.1 搜索 API

Elasticsearch 提供了基于 RESTful API 的搜索接口,可以通过 HTTP 请求进行搜索操作。

GET /<index>/_search
{
"query": { ... }
}

  • GET /<index>/_search: 在指定的索引中执行搜索。
  • query: 查询语句,定义了搜索条件。

2.2 查询类型

Elasticsearch 提供了丰富的查询类型,以下是一些常用的查询类型:

  • Match Query (匹配查询): 标准查询,对指定字段进行全文搜索,会进行分词处理。

    json
    {
    "query": {
    "match": {
    "description": "Elasticsearch tutorial"
    }
    }
    }

  • Term Query (词项查询): 精确值查询,不会进行分词处理,用于查询 keyword 类型的字段。

    json
    {
    "query": {
    "term": {
    "category": "electronics"
    }
    }
    }

  • Range Query (范围查询): 用于查询指定范围内的值。

    json
    {
    "query": {
    "range": {
    "price": {
    "gte": 10,
    "lte": 100
    }
    }
    }
    }

    gte表示大于等于,lte表示小于等于,还有gt(大于),lt(小于)

  • Bool Query (布尔查询): 组合多个查询条件,支持 must (与), should (或), must_not (非)。

    json
    {
    "query": {
    "bool": {
    "must": [
    { "match": { "name": "Elasticsearch" } },
    { "range": { "price": { "gte": 50 } } }
    ],
    "must_not": [
    { "term": { "category": "books" } }
    ]
    }
    }
    }

  • Wildcard Query(通配符查询): 使用通配符进行模糊查询,* 表示匹配任意个字符,? 表示匹配单个字符。

    json
    {
    "query": {
    "wildcard": {
    "name": "elast*"
    }
    }
    }

  • Prefix Query(前缀查询): 查询以特定前缀开头的文档

    json
    {
    "query": {
    "prefix": {
    "name": "elast"
    }
    }
    }

除了以上列举的查询类型,Elasticsearch 还支持其他更复杂的查询类型,例如 Fuzzy Query (模糊查询), Regexp Query (正则查询) 等。

2.3 排序 (Sorting)

搜索结果可以根据指定字段进行排序。

json
{
"query": {
"match_all": {}
},
"sort": [
{ "price": "desc" }
]
}

  • sort: 排序规则,可以指定多个排序字段。
  • price: 排序字段。
  • desc: 降序排序,asc 为升序排序。

2.4 分页 (Pagination)

对于大量数据的搜索结果,可以使用分页来分批获取数据。

json
{
"query": {
"match_all": {}
},
"from": 10,
"size": 20
}

  • from: 起始位置,从 0 开始。
  • size: 每页数量。

三、 分析:理解文本的奥秘

分析 (Analysis) 是将文本转换成一系列的词项 (Terms) 的过程,这些词项用于构建倒排索引,以便进行快速的全文搜索。

3.1 分析器 (Analyzer)

分析器是 Elasticsearch 中用于执行分析过程的组件。一个分析器通常包含三个部分:

  • 字符过滤器 (Character Filters): 在分词之前对文本进行预处理,例如去除 HTML 标签、转换字符等。
  • 分词器 (Tokenizer): 将文本分割成一系列的词项。
  • 词项过滤器 (Token Filters): 对分词器输出的词项进行处理,例如转换为小写、删除停用词、添加同义词等。

3.2 内置分析器

Elasticsearch 提供了多种内置分析器,可以直接使用或进行自定义配置:

  • Standard Analyzer (标准分析器): 默认的分析器,适用于大多数欧洲语言。它基于 Unicode 文本分割算法进行分词,并删除大多数标点符号,最后将所有词项转换为小写。
  • Simple Analyzer (简单分析器): 将文本按照非字母字符进行分割,并将所有词项转换为小写。
  • Whitespace Analyzer (空格分析器): 仅按照空格进行分割。
  • Keyword Analyzer (关键词分析器): 不进行分词,将整个文本作为一个词项。
  • Language Analyzers (语言分析器): 针对特定语言的分析器,例如 english 分析器、chinese 分析器等。

3.3 中文分词

由于中文的复杂性,需要使用特定的中文分词器来处理中文文本。常用的中文分词器包括:

  • IK Analyzer: 一个流行的开源中文分词器,支持自定义词典和多种分词策略。
  • jieba: Python 中常用的中文分词工具,也提供了 Elasticsearch 插件。

要在 Elasticsearch 中使用中文分词器,需要安装相应的插件,并在创建索引时指定字段使用中文分词器。

示例: 使用 IK Analyzer 对 description 字段进行中文分词。

json
PUT /products
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"description": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}

  • analyzer: 指定索引时使用的分词器,ik_max_word 会将文本进行最细粒度的拆分。
  • search_analyzer: 指定搜索时使用的分词器,ik_smart 会根据上下文进行智能分词。

四、 总结

本文详细介绍了 Elasticsearch 的三个核心概念:索引、搜索和分析。

  • 索引 是 Elasticsearch 存储数据的基本单位,通过分片和副本机制实现了高可用性和可扩展性。映射定义了索引的文档结构,可以根据需要进行自定义配置。
  • 搜索 是 Elasticsearch 的核心功能,提供了丰富的查询类型和灵活的搜索 API,可以满足各种复杂的搜索需求。
  • 分析 是将文本转换成词项的过程,通过分析器来实现。Elasticsearch 提供了多种内置分析器,并支持自定义分析器和中文分词器。

掌握了这些核心概念,您就可以开始使用 Elasticsearch 构建强大的搜索引擎了。

希望这篇教程能够帮助您入门 Elasticsearch! 请记住,这只是一个开始。Elasticsearch 还有许多高级功能等待您去探索,例如聚合、脚本、地理空间搜索等。请继续学习和实践,深入了解 Elasticsearch 的强大功能,并将其应用到您的实际项目中。

THE END