热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ElasticSearch的一些概念

ElasticSearch是个天然分布式的搜索引擎,有一些核心概念与传统的数据库知识区别很大,这里做一下记录和整理。分布式相关集群一个集群cluster由一个或者多个节点组成,

ElasticSearch是个天然分布式的搜索引擎,有一些核心概念与传统的数据库知识区别很大,这里做一下记录和整理。

分布式相关

集群

一个集群cluster由一个或者多个节点组成,具有相同的cluster.name,协同工作,分项数据和负载。当有新的节点加入或者删除了一个节点时,集群回感知到并能够平衡数据。
ElasticSearch中可以监控很多信息,有一个最重要的就是集群健康。集群健康有三个状态:green(所有主要分片和复制分片都可用),yellow(所有主要分片可用,但不是所有复制分片都可用),red(不是所有的主要分片都可用)。

节点

一个节点node就是一个ElasticSearch的实例。
集群中的一个节点会被选举为主节点master,它将临时管理集群级别的一些变更,譬如新建或者删除索引、增加或者移除节点等等。主节点不参与文档级别的变更或者搜索,所以不会成为集群的瓶颈。任何节点都可以成为主节点。
用户能够与集群中的任何节点通信,包括主节点。每一个节点都知道文档存在于哪个节点上,可以转发请求到相应的节点上。

分片

一个分片shard是一个最小级别的工作单元,仅保存了索引中所有数据的一部分。
分片就是一个Lucene实例,并且它本身就是一个完整的搜索引擎。
文档存储在分片中,并且在分片中被索引,但是程序不会直接与分片通信,而是与索引通信。

主分片

索引中的每个文档属于一个单独的主分片,所以主分片的数量决定了索引最多能存储多少数据。
索引创建完成时,主分片的数量就固定了,但是复制分片的数量可以随时调整。

复制分片

复制分片仅仅是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,比如搜索或者从别的shard取回文档。


元数据相关

一个文档不仅仅有数据,还包含了元数据(关于文档的信息)。三个必须的元数据节点是:_index,_type,_id。

索引

_inde,文档存储的地方,类似于关系型数据中的数据库。
事实上,数据被存储和索引在分片中,索引仅仅是一个把一个或者多个分片分组在一起的逻辑空间。
索引名字必须是全部小写,不允许以下划线开头,不能包含逗号。

类型

_type,对应于关系型数据库中的表。
每个类型type都有自己的映射或者结构定义,就像传统数据库表中的列一样。类型的映射会告诉ElasticSearch文档如何被索引。
_type的名字可以是大写或者小写,不能包含下划线或者逗号。

文档

文档id是一个字符串,与_index和_type组合时,就可以在ElasticSearch中唯一标识一个文档。创建文档时,可以自定义_id,也可以让ES帮助自动生成。


数据操作相关

数据相关的操作有:
索引一个文档;PUT。
检索文档,检索文档的一部分;GET,以及_source参数。
检索文档是否存在;HEAD(返回200或者404)。
更新整个文档;PUT。
创建新的文档;POST(冲突时返回409)。
删除文档;DELETE(返回200或者404)。
文档局部更新;POST,以及_update参数。
检索多个文档;_mget参数指令,docs数组参数。
批量更新;_bulk参数指令,可以包含create,index,update,delete动作。

搜索

ElasticSearch不仅会存储文档,还会索引文档内容使之可以被搜索。
搜索使用_search指令。
返回内容包括hits,took,shards,timeout。
分页参数包括from以及size,要特别关注深度分页。


映射

映射是指数据在每个字段中的解释说明。
映射机制用于进行字段类型确认,将每个字段匹配为一种确定的数据类型(string,number,boolean,date等)。
_mapping参数指令用于参数某index下某type的映射情况。
不同类型的字段的索引方式是不同的,因此会导致查询结果不同。
ElasticSearch中的数据大致分为两类:确切值,全文文本。这也是ES区别于别的数据库的根本差异。

确切值

确切值是确定的。

全文文本

全文文本,从某个角度来讲是文本化的数据,通常以人类的语言书写。

倒排索引

倒排索引由在文档中出现的唯一的单词列表,以及对于每个单词在文档中的位置组成。词terms,表征tokens。
分词,指的是标记化和标准化的过程。

核心简单字段类型

ElasticSearch支持以下简单字段类型:String(string),Whole Number(byte,short,integer,long),Floating point(float,double),Boolean(boolean),Date(date)。
当索引一个包含新字段的文档,ES将使用动态映射猜测字段类型,这个类型来自于JSON的基本数据类型(注意:如果是一个带引号的数字,ES可能将其猜测为字符串,而不是数字)。

自定义字段映射

多数情况下基本数据类型已经能够满足需求,不过也会需要自定义一些特殊类型,特别是字符串字段类型。自定义类型能够实现如下需求:
- 区分全文字符串字段和确切值字符串字段(即,是否进行分词);
- 使用特定语言的分析器;
- 优化部分匹配字段;
- 指定自定义日期格式;
- 。。。

映射的重要参数

  • type:即指定字段的类型;
  • index:控制字符串以何种方式被索引;analyzed表示全文文本形式,not_analyzed表示确切值形式 ,no表示不索引(即不能被搜索到)。string类型字段的默认值是analyzed。
  • analyzer:指定分析器(譬如whitespace,simple,english)。

复合核心字段类型

除了之前提到的简单标量类型,JSON还有null值,数组和对象;这些类型ES都支持。

多值字段

{"tag": ["elastic", "search"]}

对于数组不需要特殊的映射,任何一个字段可以包含0个,1个或者多个值,同样对于全文本字段将被分析并产生多个值。
同时这意味着数组中的所有值的类型必须统一,ES会使用数组中第一个值的类型来确定新字段的类型。
数组作为一个值的集合被对待,没有顺序。

空字段

数组也可以是空的,这等价于0个值。
Lucene没法存放null值,一个null值得字段会被认为是空字段。
如下的四个字段将被识别为空字段而不被索引。

"empty_string": "",
"null_value": null,
"empty_array": [],
"array_with_null_value": [ null ]

多层对象

内部对象经常用于在另一个对象中嵌入一个实体或者对象。
ES会动态监测新对象的字段,并映射它们为object类型,将每个字段加到properties字段下。
Lucene并不了解内部对象,一个Lucene文件包含一个键-值对应的扁平表单,所以内嵌对象的属性会通过“.”连接后的属性表示。

对象-数组

内部对象数组在Lucene中也会被扁平化处理,因而每个值的栏位会变成一个值集合,而不是有序的阵列。关联内部对象用来解决嵌套对象的问题。


分析

分析机制用于进行全文本的分词,以建立供搜索使用的反向索引。
分析的过程如下:
1.首先,标记化一个文本块为适用于倒排索引的单独的词term;
2.然后,标准化这些词为标准形式,提供它们的可搜索性或者查全率。

字符过滤器

character filter:字符过滤器的工作是在标记化之前处理字符串,字符过滤器能够去除HTML标记,或者转换“&”为“and”等工作。

分词器

tokenizer:文档被标记化为独立的词,一个简单的分词器可以根据空格或者逗号将单词分开(这个在中文中不适用)。

标记过滤

token filter:分词后每个独立的词都通过标记过滤,标记过期能够修改词(譬如将大写转换为小写,将时态进行转换),去掉词(譬如去掉“a”, “and”, “the”等连词和冠词),或者增加词(譬如同义词)。

分析器

ElasticSearch附带了一些预装的分析器,可以直接使用。

标准分析器

这是ElasticSearch默认使用的分析器。对于文本分析,它对于任何语言都是最佳选择(如果没有特殊需求的话)。标准分析器根据Unicode Consortium定义的单词边界来切分文本,然后去掉大部分的标点符号,最后把所有词转换为小写。

简单分析器

简单分析器将非单个字母的文本切分,然后把每个词转换为小写。

空格分析器

空格分析器依据空格切分文本,不转换大小写。

语言分析器

特定语言分析器适用于很多语言,能够考虑到特定语言的特性。
例如,english分析器自带一套英语停用词库,这些词被移除之后,英语单词的主体含义依旧能被理解。

注:analyze API能够查看文本是如何被分析的。


查询

简单查询语句是一种有效的命令行adhoc查询。
如果要体会搜索的强大,要是用请求体查询API,这种查询的参数以JSON格式容纳而不是查询字符串。
请求体查询并不仅仅用来处理查询,还可以高亮返回结果中的片段,并给出寻找最好结果的相关数据建议。
结构化查询是一种灵活,多表现形式的查询语言。
使用结构化查询,需要传递query参数。
查询子句:

{
    QUERY_NAME: {
        ARGUMENT: VALUE,
        ARGUMENT: VALUE,...
    }
}

查询子句像是搭积木,可以合并简单的子句为一个复杂的查询语句。

  • 叶子子句(比如match子句)用于将查询字符串与一个字段或者多个字段进行比较;
  • 复合子句(比如bool子句),用于合并其他的子句(使用must,must_not,should等进行连接);

match_all

查询所有文档,是没有查询条件下的默认语句。

match

标准查询,不论需要全文本查询还是精确查询基本上都要用到它。
如果使用match查询一个全文本字段,它会在真正查询之前用分析器先分析一下match的查询字符。
如果使用match查询确切值(譬如数字、日期、布尔值、not_analyzed字符串),ES将会搜索给定值。

multi_match

multi_match查询允许做match查询的基础上同时搜索多个字段。

bool

bool查询与bool过滤相似,用于合并多个查询子句。
不同之处在于:bool过滤可以直接给出是否匹配成功,而bool查询要计算每一个查询子句的_score。

  • must:查询指定文档一定要包含;
  • must_not:查询指定文档一定不要被包含;
  • should:查询指定文档,有则可以为文档相关性加分;

过滤

事实上有两种结构化语句:结构化查询,结构化过滤。二者非常相似,但是它们由于使用目的不同而差异。
一条过滤语句会询问每个文档的字段值是否包含特定值;
一条查询语句则询问每个文档的字段值与特定值得匹配程度如何;查询语句会计算每个文档与查询语句的相关性,给出一个相关性评分_score,并且按照相关性对匹配到的文档进行排序。
原则上来说,使用查询语句来做全文本搜索,或者需要进行相关性评分的时候;其他的情况下应该使用过滤语句。

term

term主要用于精确匹配哪些值,比如数字、日期、布尔值或者not_analyzed的字符串。

terms

terms和term有点类似,但是terms允许指定多个匹配条件。譬如某个字段指定了多个值,那么文档需要一起去做匹配。

range

range过滤允许我们按照指定范围查找一批数据。
操作符包含gt,gte,lt,lte。

exists&missing

exists和missing过滤用于查找文档中是否包含指定字段或者是否没有某个字段。

bool

bool过滤用来合并多个过滤条件的布尔逻辑。
包含如下操作符:

  • must:多个查询条件完全匹配,相当于and;
  • must_not:多个查询条件的相反匹配,相当于not;
  • should:至少有一个查询条件匹配,相当于or;

查询与过滤条件合并

查询语句和过滤语句可以放在各自的上下文中。
在ES API中可以看到许多带有query或者filter的语句,这些语句既可以包含单条query语句,也可以包含一条filter子句;也就是说,这些语句需要首先创建一个query或者filter的上下文关系。
通常情况下,一条查询语句需要过滤语句的辅助,全文本搜索除外。
search API中仅能包含query语句,所以需要用filtered来同时包含query和filter子句。
带过滤的查询语句:

GET /_search
{
    "query": {
        "filtered": {
            "query": { "match": { "email": "business opportunity" }},
            "filter": { "term": { "folder": "inbox" }}
        }
    }
}

查询语句中的过滤:

GET /_search
{
    "query": {
        "filtered": {
            "filter": {
                "bool": {
                    "must": { "term": { "folder": "inbox" }},
                    "must_not": {
                        "query": {
                            "match": { "email": "urgent business proposal" }
                        }
                    }
                }
            }
        }
    }
}

_validate API可以验证一条查询语句是否合法。


推荐阅读
  • 本文详细介绍了 InfluxDB、collectd 和 Grafana 的安装与配置流程。首先,按照启动顺序依次安装并配置 InfluxDB、collectd 和 Grafana。InfluxDB 作为时序数据库,用于存储时间序列数据;collectd 负责数据的采集与传输;Grafana 则用于数据的可视化展示。文中提供了 collectd 的官方文档链接,便于用户参考和进一步了解其配置选项。通过本指南,读者可以轻松搭建一个高效的数据监控系统。 ... [详细]
  • 微信公众号推送模板40036问题
    返回码错误码描述说明40001invalidcredential不合法的调用凭证40002invalidgrant_type不合法的grant_type40003invalidop ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 深入浅出 webpack 系列(二):实现 PostCSS 代码的编译与优化
    在前一篇文章中,我们探讨了如何通过基础配置使 Webpack 完成 ES6 代码的编译。本文将深入讲解如何利用 Webpack 实现 PostCSS 代码的编译与优化,包括配置相关插件和加载器,以提升开发效率和代码质量。我们将详细介绍每个步骤,并提供实用示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • Keepalived 提供了多种强大且灵活的后端健康检查机制,包括 HTTP_GET、SSL_GET、TCP_CHECK、SMTP_CHECK 和 MISC_CHECK 等多种检测方法。这些健康检查功能确保了高可用性环境中的服务稳定性和可靠性。通过合理配置这些检查方式,可以有效监测后端服务器的状态,及时发现并处理故障,从而提高系统的整体性能和可用性。 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • 深入探索HTTP协议的学习与实践
    在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。 ... [详细]
  • 在PHP中实现腾讯云接口签名,以完成人脸核身功能的对接与签名配置时,需要注意将文档中的POST请求改为GET请求。具体步骤包括:使用你的`secretKey`生成签名字符串`$srcStr`,格式为`GET faceid.tencentcloudapi.com?`,确保参数正确拼接,避免因请求方法错误导致的签名问题。此外,还需关注API的其他参数要求,确保请求的完整性和安全性。 ... [详细]
  • 在安装并配置了Elasticsearch后,我在尝试通过GET /_nodes请求获取节点信息时遇到了问题,收到了错误消息。为了确保请求的正确性和安全性,我需要进一步排查配置和网络设置,以确保Elasticsearch集群能够正常响应。此外,还需要检查安全设置,如防火墙规则和认证机制,以防止未经授权的访问。 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • 本文详细探讨了 jQuery 中 `ajaxSubmit` 方法的使用技巧及其应用场景。首先,介绍了如何正确引入必要的脚本文件,如 `jquery.form.js` 和 `jquery-1.8.0.min.js`。接着,通过具体示例展示了如何利用 `ajaxSubmit` 方法实现表单的异步提交,包括数据的发送、接收和处理。此外,还讨论了该方法在不同场景下的应用,如文件上传、表单验证和动态更新页面内容等,提供了丰富的代码示例和最佳实践建议。 ... [详细]
  • 技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告
    技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告 ... [详细]
  • 本文详细解析了微信服务端示例类的功能与应用。其中,`ClientResponseHandler` 类主要用于处理微信支付所需的响应数据,而 `TenpayHttpClient` 则是对 HTTP 请求(包括 GET 和 POST 方法)进行了封装,以便在内部调用时更加便捷和高效。这些工具类在实际开发中起到了关键作用,开发者无需深入了解其底层实现细节,即可轻松集成微信支付功能。 ... [详细]
  • FastDFS Nginx 扩展模块的源代码解析与技术剖析
    FastDFS Nginx 扩展模块的源代码解析与技术剖析 ... [详细]
author-avatar
痴情季豪_726
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有