雄县网站建设,评价一个网站的好坏,网站后台 添加用户,烟台网站建设公司报价Elasticsearch 是一个开源的、基于 Lucene 的分布式搜索和分析引擎#xff0c;设计用于云计算环境中#xff0c;能够实现实时的、可扩展的搜索、分析和探索全文和结构化数据。它具有高度的可扩展性#xff0c;可以在短时间内搜索和分析大量数据。 Elasticsearch 不仅仅是一个… Elasticsearch 是一个开源的、基于 Lucene 的分布式搜索和分析引擎设计用于云计算环境中能够实现实时的、可扩展的搜索、分析和探索全文和结构化数据。它具有高度的可扩展性可以在短时间内搜索和分析大量数据。 Elasticsearch 不仅仅是一个全文搜索引擎它还提供了分布式的多用户能力实时的分析以及对复杂搜索语句的处理能力使其在众多场景下如企业搜索日志和事件数据分析等都有广泛的应用。 本文将向你详细介绍什么是倒排索引、以及 Elasticsearch 查询、相关性评分和搜索优化的相关原理。 文章目录 1、倒排索引1.1、为什么需要倒排索引1.2、为什么叫倒排索引1.3、倒排索引的结构 2、数据查询过程2.1、数据查询处理原理2.2、解析查询语句2.3、生成查询计划2.4、执行查询2.5、生成查询结果 3、相关性评分3.1、相关性评分的作用3.2、TF-IDF 原理3.3、其他评分规则 4、搜索功能4.1、全文搜索4.2、多值搜索4.3、模糊搜索4.4、范围搜索4.5、聚合搜索 5、搜索优化5.1、索引优化5.2、查询优化5.3、使用doc_values优化排序和聚合5.4、使用routing优化分片5.5、其他优化 1、倒排索引
1.1、为什么需要倒排索引
倒排索引也是索引。索引初衷都是为了快速检索到你要的数据。
每种数据库都有自己要解决的问题或者说擅长的领域对应的就有自己的数据结构而不同的使用场景和数据结构需要用不同的索引才能起到最大化加快查询的目的。
对 Mysql 来说是 B 树对 Elasticsearch 和 Lucene 来说是倒排索引。
Elasticsearch 是建立在全文搜索引擎库 Lucene 基础上的搜索引擎它隐藏了 Lucene 的复杂性取而代之的提供一套简单一致的 RESTful API不过掩盖不了它底层也是 Lucene 的事实。Elasticsearch 的倒排索引其实就是 Lucene 的倒排索引。
1.2、为什么叫倒排索引
“倒排索引”Inverted Index的概念是从正向索引Forward Index中衍生出来的。
在正向索引中我们从文档出发记录下每个文档中出现的词项这样就可以知道每个文档包含哪些词项。而在倒排索引中我们从词项出发记录下每个词项出现在哪些文档中这样就可以知道每个词项被哪些文档包含。
正向索引document - to - words
倒排索引word - to - documents因此“倒排索引可以看作是正向索引的逆操作所以被称为倒排”。在全文搜索中倒排索引是非常重要的数据结构因为它可以让我们快速找到包含特定词项的所有文档。
1.3、倒排索引的结构
倒排索引作为一种数据结构用于存储一种映射关系即从词项到出现该词项的文档的映射。它是全文搜索引擎的核心组成部分如 Elasticsearch、Lucene 等。
在倒排索引中每个唯一的词项都有一个相关的倒排列表这个列表中包含了所有包含该词项的文档的 ID。这样当我们搜索一个词项时搜索引擎只需要查找倒排索引就可以快速找到所有包含这个词项的文档。
例如假设我们有以下三个文档
1. 文档1I love coding
2. 文档2I love reading
3. 文档3I love both对这些文档建立倒排索引后我们会得到以下的映射关系
- I文档1文档2文档3
- love文档1文档2文档3
- coding文档1
- reading文档2
- both文档3所以当我们搜索love时搜索引擎会在倒排索引中找到love然后返回所有包含love的文档即文档1文档2 和文档3。 2、数据查询过程
2.1、数据查询处理原理
在 Elasticsearch 中查询处理主要包括以下步骤
解析查询语句首先Elasticsearch 会解析用户的查询请求将其转换为内部的查询表示。这个过程包括解析查询语句的语法、解析查询参数、验证查询语句的合法性等。生成查询计划解析查询语句后Elasticsearch 会生成一个查询计划。查询计划描述了如何在倒排索引上执行查询包括哪些词项需要查询、如何组合词项的查询结果等。执行查询有了查询计划后Elasticsearch 就可以在倒排索引上执行查询了。这个过程包括查找词项的倒排列表、计算文档和查询的相关性、生成候选结果集等。生成查询结果最后Elasticsearch 会根据候选结果集和查询参数生成最终的查询结果。这个过程包括排序候选结果、生成摘要、分页等。
2.2、解析查询语句
在 Elasticsearch 中解析查询语句是查询处理的第一步。这个过程主要包括以下步骤
解析 JSONElasticsearch 的查询语句通常以 JSON 格式提供。首先Elasticsearch 会解析 JSON将其转换为内部的数据结构。
{query: {match: {field_name: query_value}}
}解析查询类型查询语句中通常会指定查询类型包括 Match 查询用于基本的全文搜索Term 查询用于精确匹配Range 查询用于范围搜索Bool 查询用于逻辑组合多个查询条件Phrase 查询用于短语搜索Wildcard 查询用于通配符搜索Prefix 查询用于前缀搜索以及 Fuzzy 查询用于模糊搜索等。Elasticsearch 会解析查询类型并根据查询类型选择相应的查询处理器。解析查询参数查询语句中还会包含一些查询参数如字段名、查询值、模糊匹配的阈值等。Elasticsearch 会解析这些查询参数并将它们传递给查询处理器。验证查询语句最后Elasticsearch 会验证查询语句的合法性。例如检查字段名是否存在检查查询值的类型是否与字段类型匹配等。如果查询语句不合法Elasticsearch 会返回一个错误。
2.3、生成查询计划
在 Elasticsearch 中生成查询计划的过程包括确定查询类型如 match、term、range 等确定要查询的字段和值然后根据这些信息生成查询计划描述了如何在倒排索引上执行查询包括哪些词项需要查询以及如何组合词项的查询结果。
2.4、执行查询
在 Elasticsearch 中执行查询是查询处理过程的关键步骤。这个过程主要包括以下步骤 查找词项根据查询计划Elasticsearch 会在倒排索引中查找每个词项的倒排列表。 计算相关性Elasticsearch 会计算每个文档和查询的相关性。这通常通过一个名为 TF-IDF 的算法来完成。 生成候选结果集Elasticsearch 会根据相关性的计算结果生成一个候选结果集。这个结果集包含了所有可能满足查询条件的文档。
2.5、生成查询结果
在 Elasticsearch 中生成查询结果是查询处理过程的最后一步。这个过程主要包括以下步骤 排序Elasticsearch 会根据每个文档和查询的相关性对候选结果集进行排序。 生成摘要为了方便用户查看查询结果Elasticsearch 会为每个文档生成一个摘要。摘要通常包括文档的一部分内容和查询词项的位置。 分页如果查询请求中指定了分页参数Elasticsearch 会根据这些参数从排序后的结果集中提取出一个页面的结果。 返回结果最后Elasticsearch 会将查询结果返回给用户。查询结果通常以 JSON 格式提供包括总的命中数、查询时间、每个文档的 ID、摘要等信息。
以上就是 Elasticsearch 生成查询结果的基本过程。需要注意的是这个过程可能会受到查询语句的复杂性、数据量的大小、集群的状态等因素的影响。 3、相关性评分
3.1、相关性评分的作用
在 Elasticsearch 中相关性评分也称为评分或得分是用来衡量一个文档与查询条件的匹配程度的。它是由 Elasticsearch 的查询模块根据 TF-IDF 算法或其他相关性算法计算出来的一个数值。
相关性评分的作用主要体现在以下几个方面 排序在返回查询结果时Elasticsearch 会根据相关性评分对结果进行排序。评分越高的文档被认为与查询条件的匹配程度越高因此会被排在更前面。**** 筛选在某些情况下你可能只关心那些与查询条件高度匹配的文档。这时你可以设置一个评分阈值只返回评分高于这个阈值的文档。 调优通过理解和调整相关性评分的计算方式你可以优化查询的效果使其更符合你的需求。例如你可以通过设置字段的权重影响其在评分计算中的重要性。
需要注意的是相关性评分并不是一个绝对的值它的大小并不能直接反映出文档的质量或重要性。它只是表示了文档与特定查询条件的匹配程度。同一个文档对于不同的查询条件可能会有不同的评分。
3.2、TF-IDF 原理
TF-IDF词频-逆文档频率算法用于评估一个词对于一个文件集或语料库中的某个文件的重要程度。它的工作原理如下 Term Frequency (TF)衡量一个词在文档中出现的频率。计算方法通常是将文档中某个词出现的次数除以文档中所有词的总数。TF 值越高表示该词在文档中的重要性越高。 Inverse Document Frequency (IDF)衡量一个词是否常见。计算方法是将语料库中的文档总数除以包含该词的文档数的对数。IDF 值越高表示该词的信息量越大对于区分文档的重要性越高。 TF-IDF 值计算将 TF 值和 IDF 值相乘得到最终的 TF-IDF 值。TF-IDF 值越高表示该词对于某个文档的重要性越高。
在 Elasticsearch 中对于每个查询词会计算它在文档中的 TF 值和在整个语料库中的 IDF 值然后将这两个值相乘得到最终的 TF-IDF 值。查询结果按照 TF-IDF 值的大小进行排序TF-IDF 值越大表示文档和查询的相关性越高。
TF-IDF 算法的目标是通过考虑词频和词的普遍性来确定词的重要性从而提高信息检索的准确性和相关性。
3.3、其他评分规则
除了基于 TF-IDF 的相关性评分外Elasticsearch 还提供了其他的评分规则以满足不同的搜索需求。以下是一些常见的评分规则
Constant Score这种评分规则会给所有的文档赋予相同的评分。它通常用于过滤操作因为在过滤操作中我们只关心文档是否满足条件而不关心文档的相关性。Boolean/Disjunction Max Score这种评分规则会计算每个查询条件的评分然后取最高的评分作为最终的评分。它通常用于多条件查询因为在多条件查询中我们通常关心的是文档满足任何一个条件的程度。Function Score这种评分规则允许你自定义评分函数以实现复杂的评分逻辑。你可以基于文档的字段值、查询参数、脚本等因素计算出一个评分。
以上只是 Elasticsearch 评分规则的一部分实际上 Elasticsearch 还提供了更多的评分规则如 script_score、field_value_factor、decay functions 等可以满足各种复杂的搜索需求。 4、搜索功能
Elasticsearch 提供了一些高级搜索功能如全文搜索、模糊搜索、范围搜索、聚合搜索等。
4.1、全文搜索
Elasticsearch 最基本且核心的功能就是全文搜索。全文搜索是指对大量文本数据进行搜索找出包含指定词项的文档。Elasticsearch 使用倒排索引这种数据结构来实现高效的全文搜索。
全文搜索的工作原理主要基于倒排索引。倒排索引是一种数据结构它将所有的词项Term映射到出现这些词项的文档列表。当执行全文搜索时Elasticsearch 会根据查询的词项找到对应的文档列表然后根据一定的评分规则如 TF-IDF计算每个文档的相关性得分并按得分排序返回结果。
Elasticsearch 的全文搜索支持多种查询类型如 match 查询、multi_match 查询、query_string 查询等。这些查询类型可以满足各种复杂的搜索需求如单词搜索、短语搜索、布尔搜索等。
4.2、多值搜索
在 Elasticsearch 中如果你需要对多个值进行搜索可以使用 terms 查询。terms 查询允许你指定一个字段和多个值Elasticsearch 会返回所有字段值在这些值中的文档。
terms 查询的工作原理是将每个值都转换为一个 term 查询然后将这些 term 查询以 OR 的方式进行组合。这意味着只要文档的字段值匹配了任何一个值就会被认为满足查询条件。
例如如果你执行一个 terms 查询查找颜色为 “红色” 或 “蓝色” 的商品Elasticsearch 会首先在倒排索引中查找 “红色” 和 “蓝色” 这两个词项的倒排列表然后将这两个列表进行合并得到最终的结果。
需要注意的是terms 查询只适用于精确值的匹配不适用于全文搜索。如果你需要对多个词项进行全文搜索可以使用 multi_match 查询或 query_string 查询。
4.3、模糊搜索
Elasticsearch 的模糊搜索是一种能够处理拼写错误和近似搜索的功能。
模糊搜索的实现主要基于编辑距离Levenshtein distance算法该算法可以计算两个词项之间的差异程度。编辑距离是通过计算从一个词项变换到另一个词项所需的最少单字符编辑操作如插入、删除、替换的数量来衡量差异程度。
在 Elasticsearch 中可以使用 fuzzy 查询来进行模糊搜索。fuzzy 查询允许你指定一个 fuzziness 参数该参数决定了允许的最大编辑距离。例如fuzziness 参数设置为 1那么就可以匹配出与查询词项编辑距离在 1 以内的所有词项。
模糊搜索非常适合处理用户输入错误的情况可以提高搜索的容错性从而提升用户体验。
4.4、范围搜索
Elasticsearch 的范围搜索允许你查找字段值在指定范围内的文档。
范围搜索在 Elasticsearch 中主要通过 range 查询来实现。在 range 查询中你可以为字段指定一个上界和一个下界Elasticsearch 会返回所有字段值在这个范围内的文档。
例如你可以查找价格在 10 到 20 之间的所有商品或者查找发布日期在过去一周内的所有文章。
range 查询支持数值字段、日期字段、IP 地址字段等多种类型的字段。对于日期字段你还可以使用日期数学表达式来指定范围如 now-1d 表示从现在开始的过去一天。
此外range 查询还支持开闭区间的设置你可以通过 gte大于等于、gt大于、lte小于等于、lt小于等参数来控制区间的开闭。
范围搜索是 Elasticsearch 中非常常用的一种搜索方式它可以满足各种基于范围的过滤和查询需求。
4.5、聚合搜索
Elasticsearch 的聚合搜索是一种强大的数据分析工具它允许你在搜索结果上进行各种统计分析。
聚合搜索在 Elasticsearch 中主要通过聚合Aggregations功能来实现。聚合功能提供了一组用于数据分析的操作符如 min、max、avg、sum、count 等你可以使用这些操作符来对搜索结果进行统计分析。
例如你可以使用 avg 聚合来计算所有商品的平均价格或者使用 histogram 聚合来统计每个价格区间的商品数量。
此外聚合功能还支持嵌套聚合你可以在一个聚合的基础上进行另一个聚合。这使得你可以实现复杂的数据分析需求如分组统计、多级分组统计等。
聚合搜索是 Elasticsearch 中非常强大的一种功能它可以满足各种复杂的数据分析需求。 5、搜索优化
5.1、索引优化
在 Elasticsearch 中优化索引结构是提高搜索性能的重要手段。以下是一些常见的索引优化策略 合理设置分片数量每个索引都可以分为多个分片每个分片是索引数据的一个独立部分。分片的数量会影响 Elasticsearch 的并行处理能力但是过多的分片会增加集群的管理负担可能会降低性能。因此需要根据数据量、硬件资源等因素合理设置分片的数量。 使用合适的字段类型Elasticsearch 支持多种字段类型不同的字段类型有不同的索引和搜索性能。例如对于需要全文搜索的字段应该使用 text 类型因为 text 类型会对字段值进行分词处理适合全文搜索对于需要精确匹配的字段应该使用 keyword 类型因为 keyword 类型不会对字段值进行分词处理适合精确匹配。 禁用不需要搜索的字段的索引如果一个字段不需要被搜索那么就没有必要为它建立索引。你可以在映射中将这个字段的 index 参数设置为 false这样 Elasticsearch 就不会为这个字段建立索引可以节省存储空间提高索引和搜索性能。 优化文档结构尽量避免使用嵌套类型nested type因为嵌套类型会增加索引的复杂性和存储开销。如果需要在数组字段上进行搜索可以考虑使用 flattened 类型。
以上只是优化 Elasticsearch 索引结构的一部分方法实际上还有很多其他的优化技术和策略如使用 doc_values 优化排序和聚合、使用 routing 优化分片访问等。
5.2、查询优化
在 Elasticsearch 中优化查询语句是提高搜索性能的重要手段。以下是一些常见的查询优化策略 避免使用高开销的查询某些类型的查询如 wildcard、regexp、fuzzy 等由于需要对大量的词项进行匹配所以开销较大。在性能敏感的场景下应尽量避免使用这些查询。 优先使用 filter在 Elasticsearch 中filter 和 query 都可以用来过滤文档但是 filter 的结果可以被缓存下次执行相同的 filter 时可以直接使用缓存从而提高性能。因此对于那些不需要计算相关性得分的过滤条件应优先使用 filter。 避免深度分页深度分页指的是获取结果的后面几页如第 1000 页。深度分页需要 Elasticsearch 对前面所有的结果进行排序开销较大。如果需要处理大量的结果应考虑使用 scroll API 或 search_after 参数。 减少返回的字段默认情况下Elasticsearch 会返回文档的所有字段。如果只需要文档的部分字段可以使用 _source 参数来指定返回的字段这样可以减少网络传输的数据量提高性能。
以上只是优化 Elasticsearch 查询语句的一部分方法实际上还有很多其他的优化技术和策略如使用 bool 查询的 must、should、filter、must_not 来优化布尔逻辑使用 constant_score 查询来优化静态得分等。
5.3、使用doc_values优化排序和聚合
在 Elasticsearch 中doc_values 是一种在磁盘上的列式存储它可以用来快速、高效地执行排序、聚合等操作。
当你对一个字段进行排序或聚合时Elasticsearch 需要访问该字段的所有值。如果这些值存储在文档中那么 Elasticsearch 就需要从磁盘中加载每个文档这可能会非常慢。而 doc_values 则将字段的值存储在磁盘的一个单独的区域Elasticsearch 可以直接访问这些值无需加载文档因此可以大大提高性能。
默认情况下Elasticsearch 会为所有的 keyword 类型和数值类型的字段启用 doc_values。如果你有一个 text 类型的字段也需要进行排序或聚合那么你可以为该字段添加一个 keyword 类型的子字段并启用 doc_values。
需要注意的是虽然 doc_values 可以提高排序和聚合的性能但它也会占用额外的磁盘空间。因此对于不需要排序或聚合的字段你可以在映射中将 doc_values 设置为 false以节省磁盘空间。
5.4、使用routing优化分片
在 Elasticsearch 中routing 参数可以用来控制文档存储到哪个分片以及搜索请求路由到哪个分片。通过合理的路由策略可以显著提高搜索性能。
默认情况下Elasticsearch 会根据文档的 ID 来决定将文档存储到哪个分片搜索请求会路由到所有的分片。这种策略可以保证数据的均匀分布但在某些情况下可能并不高效。
例如如果你的索引包含了多个用户的数据每次搜索请求只涉及到一个用户的数据那么默认的路由策略就会导致很多无效的搜索因为大部分分片并不包含该用户的数据。
这时你可以使用 routing 参数来优化分片访问。你可以将用户 ID 作为 routing 参数的值这样同一个用户的所有文档就会被存储到同一个分片搜索请求也只会路由到该分片。这样可以大大减少无效的搜索提高搜索性能。
需要注意的是虽然 routing 参数可以提高搜索性能但如果使用不当也可能导致数据分布不均影响集群的稳定性。因此在使用 routing 参数时需要充分考虑数据的分布情况。
5.5、其他优化
除上述两种还可以考虑
使用缓存Elasticsearch 提供了查询结果缓存和字段数据缓存可以提高重复查询的性能。需要注意的是缓存并不总是有益的如果查询模式具有很高的随机性缓存可能会降低性能。硬件优化提升硬件性能也可以提高搜索性能如增加内存可以提高缓存效果使用 SSD 可以提高 IO 性能等。