elasticsearch是基于json 属于restful风格
对应到关系数据库
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields
Elasticsearch集群可以包含多个索引(数据库),每一个索引可以包含多个类型(表),每一个类型包含多个文档(行),然后每个文档包含多个字段(列)。
Elasticsearch在各种文本字段中进行全文搜索,并且返回相关性最大的结果集。相关性的概念在Elasticsearch中非常重要,而这个概念在传统关系型数据库中是不可想象的,因为传统数据库对记录的查询只有匹配或者不匹配。
搜索:类似于like 但功能更强大 相比于like只有匹配不匹配 它只是对匹配的结果进行排序 不那么匹配的结果也会展示
聚合:类似于group by 同上
Elasticsearch为分布式而生,而且它的设计隐藏了分布式本身的复杂性。Elasticsearch在分布式概念上做了很大程度上的透明化,在教程中你不需要知道任何关于分布式系统、分片、集群发现或者其他大量的分布式概念。所有的教程你既可以运行在你的笔记本上,也可以运行在拥有100个节点的集群上,其工作方式是一样的。
Elasticsearch致力于隐藏分布式系统的复杂性。以下这些操作都是在底层自动完成的:
- 将你的文档分区到不同的容器或者分片中,它们可以存在于一个或多个节点中。
- 将分片均匀的分配到各个节点,对索引和搜索做负载均衡。
- 冗余每一个分片,防止硬件故障造成的数据丢失。
- 将集群中任意一个节点上的请求路由到相应数据所在的节点。
- 无论是增加节点,还是移除节点,分片都可以做到无缝的扩展和迁移。
一次性遍历,建立统计,通过冗余存储反向关系,来避免一直需要关系数据库需要次次全表扫描才能得到的结果
索引类似于关系型数据库里的“数据库”——它是我们存储和索引关联数据的地方。 事实上,我们的数据被存储和索引在分片(shards)中,索引只是一个把一个或多个分片分组在一起的逻辑空间。
增删改查
_index、_type、_id唯一确定一个文档 文档可以自己选定或es自动生成
获取 检索 _source 可以检索一部分
存在 head检查是否存在
更新 不可变 只是先标记之前失效然后创建新的 通过版本号区别 空间不够后删除这些失效的或者直接删除
创建 加_create,若是已存在,则创建失败
删除 不过找没找到,只要操作发生了 version仍会增加
版本控制 通过version 乐观锁 或通过外部版本号来跳跃性变化版本号,若是新的制定外部版本号不大于当前 则失败
retry_on_conflict 操作失败了重试
psert参数定义文档来使其不存在时被创建
_source 可以检索一部分
pretty 美化返回
mget 检索多个文档
bulk 更新的批量操作 每个子请求都被独立的执行,所以一个子请求的错误并不影响其它请求
bool 子句允许你合并其他的合法子句
validate
可以验证一条查询语句是否合法。 想知道语句非法的具体错误信息,需要加上 explain
参数分布式增删改查
哈希路由,主分片的数量只能在创建索引时定义且不能修改
我们能够发送请求给集群中任意一个节点。每个节点都有能力处理任意请求。每个节点都知道任意文档所在的节点,所以也可以将请求转发到需要的节点。
所有节点返回匹配文档的id和排序的值 请求节点汇总得到全局有序的结果后根据id去各节点取相应的文档
写:任意一个节点都可以接受请求,然后转发到文档归属主分片所在的节点去,主节点做完操作后同步到复制节点去,全部同步成功后,由请求的节点返回结果
/_search
在所有索引的所有类型中搜索
/_all/user,tweet/_search
在所有索引的user和tweet中搜索 search types user and tweet in all indices
搜索一个索引有5个主分片和5个索引各有一个分片事实上是一样的。
一个搜索请求常常涉及多个分片。每个分片生成自己排好序的结果,它们接着需要集中起来排序以确保整体排序正确。
现在假设我们请求第1000页——结果10001到10010。工作方式都相同,不同的是每个分片都必须产生顶端的10010个结果。然后请求节点排序这50050个结果并丢弃50040个!
1.通过查询字符串查询
2.通过json请求体查询
"+"前缀表示语句匹配条件必须被满足。类似的"-"前缀表示条件必须不被满足。所有条件如果没有+或-表示是可选的——匹配越多,相关的文档就越多。
当你索引一个文档,Elasticsearch把所有字符串字段值连接起来放在一个大字符串中,它被索引为一个特殊的字段_all.所以搜索时如果不加指明字段 只要这个all里有匹配查询词的 那么这个文档就会匹配
Elasticsearch为对字段类型进行猜测,动态生成了字段和类型的映射关系。date字段可能会被被识别为date类型。_all因为是默认字段所以没有在此显示,不过我们知道它是string类型。
date类型的字段和string类型的字段的索引方式是不同的,因此导致查询结果的不同
Elasticsearch中的数据可以大致分为两种类型:确切值 及 全文文本。
确切值希望完全匹配 而全文文本人们更关注的是匹配程度 而不是简单的匹配不匹配 这是 区分搜索引擎和其他数据库的根本差异。
你可以向已有映射中增加字段,但你不能修改它。如果一个字段在映射中已经存在,这可能意味着那个字段的数据已经被索引。如果你改变了字段映射,那已经被索引的数据将错误并且不能被正确的搜索到。
分词:
1.字符过滤器 2.分词器 3.标记过滤器
Elasticsearch 会动态的检测新对象的字段,并且映射它们为 object 类型,将每个字段加到 properties 字段下
两种结构化语句: 结构化查询和结构化过滤
一条过滤语句会询问每个文档的字段值是否包含着特定值
查询语句会询问每个文档的字段值与特定值的匹配程度如何。一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score,并且 按照相关性对匹配到的文档进行排序。
过滤
1.term/terms过滤 主要用于精确匹配哪些值/多个匹配条件
2.range过滤 range过滤允许我们按照指定范围查找一批数据
3.exists和missing过滤 exists 和 missing 过滤可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL条件
4.bool过滤 bool过滤可以用来合并多个过滤条件查询结果的布尔逻辑 must must_not should
查询
5.match_all查询 使用match_all 可以查询到所有文档,是没有查询条件下的默认语句
6.match查询
如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析match一下查询字符
如果用match下指定了一个确切值,在遇到数字,日期,布尔值或者not_analyzed 的字符串时,它将为你搜索你给定的值
提示: 做精确匹配搜索时,你最好用过滤语句,因为过滤语句可以缓存数据。
7. multi_match查询 它允许你做match查询的基础上同时搜索多个字段
8.bool查询 bool查询与 bool过滤相似,用于合并多个查询子句。不同的是,bool过滤可以直接给出是否匹配成功, 而bool 查询要计算每一个查询子句的 _score。
search API中只能包含 query 语句,所以我们需要用 filtered 来同时包含 "query" 和 "filter" 子句。 在外层再加入 query 的上下文关系
如果一条查询语句没有指定查询范围,那么它默认使用
match_all
查询排序
过滤语句不排序,
_score
设值为 1,
计算 _score
是比较消耗性能的, 而且通常主要用作排序 -- 我们不是用相关性进行排序的时候,就不需要统计其相关性。 如果你想强制计算其相关性,可以设置track_scores
为 true
。字段值默认以顺序排列,而
_score
默认以倒序排列对于集合, 可以使用
min
, max
, avg
或 sum
这些模式在集合中选出一个想要作为排序的比较相关性计算
检索词频率
出现频率越高,相关性也越高。 字段中出现过5次要比只出现过1次的相关性高。
反向文档频率
频率越高,相关性越低。 检索词出现在多数文档中会比出现在少数文档中的权重更低, 即检验一个检索词在文档中的普遍重要性。
字段长度准则
长度越长,相关性越低。 检索词出现在一个短的
title
要比同样的词出现在一个长的 content
字段相关性大。搜索类型
1.count 计数
2.query_and_fetch 查询并且取回 搜索类型将查询和取回阶段合并成一个步骤
3.dfs_query_then_fetch和dfs_query_and_fetch
4.scan 扫描 禁止排序来高效取回巨大数量的结果 避免深分页 常配合滚屏一起用
字符过滤器 分词器 标记过滤器
keyword分词器输出和它接收到的相同的字符串,不做任何分词处理。[
whitespace
分词器]只通过空格来分割文本。[pattern
分词器]可以通过正则表达式来分割文本尽量避免命名冲突,在其他里面通过全限定名在找到一个 但此处是搜索 忽略了层级 所以会产生冲突 因此即使是不同域的命名也不要相同
文档主体保存在
_source
字段中 _all
字段:一个所有其他字段值的特殊字符串字段相对于完全禁用
_all
字段,你可以先默认禁用 include_in_all
选项,而选定字段上启用 include_in_all 按需启用
动态映射
dynamic 当动态添加新的索引时
true
:自动添加字段(默认)false
:忽略字段strict
:当遇到未知字段时抛出异常设置
mappings
dynamic_templates 设置动态模板
date_detection 日期检测
_default_ 默认呢映射模板
settings
number_of_shards
定义一个索引的主分片个数,默认值是 `5`。这个配置在索引创建后不能修改。
number_of_replicas
每个主分片的复制分片个数,默认是 `1`。这个配置可以随时在活跃的索引上修改。
analysis 分析器
refresh_interval 索引刷新频率
_alias
用于单个别名操作_aliases
用于原子化多个别名操作。
预先使用别名 万一需要迁移只需修改别名指向就可以无缝迁移
写入磁盘的文件不可变 通过多个索引来更新倒排索引,被打上失效标志的文档会从结果中删除
新建索引加入文件系统缓存,新的端可被打开 通过refresh完成,同时为了一方面减少磁盘写入次数 一方面防止没来得及写入的文档丢失 加上日志记录
1.当一个文档被索引,它被加入到内存缓存,同时加到事务日志。
2. refresh使得分片的进入如下图描述的状态。每秒分片都进行refeash:
- 内存缓冲区的文档写入到段中,但没有fsync。
- 段被打开,使得新的文档可以搜索
- 缓存被清除
3.随着更多的文档加入到缓存区,写入日志,这个过程会继续
4.不时地,比如日志很大了,新的日志会创建,会进行一次全提交:
- 内存缓存区的所有文档会写入到新段中。
- 清除缓存
- 一个提交点写入硬盘
- 文件系统缓存通过fsync操作flush到硬盘
- 事务日志被清除
通过fresh完成,而且因为日志是实时的 所以可以来这里找到最新的值
合并段 通过optimize完成
- 新的段flush到了硬盘。
- 新的提交点写入新的段,排除旧的段。
- 新的段打开供搜索。
- 旧的段被删除。
过滤
查询时过滤条件会产生位图来表示该过滤条件的结果,再次查询时过滤先执行,得到缓存的位图,然后去告诉query跳过相应的结果。而且过滤条件把权重都视为一样 所以无需计算相关性,
而且位图是实时更新的而且只要是过滤条件相同位图都相同,但只是缓存枝叶型过滤器,组合的过滤器查询结果不缓存,因为它可以通过前者的通过逻辑运算组合
gt
:>
大于lt
:<
小于gte
:>=
大于或等于lte
:<=
小于或等于
term
和 terms
是包含操作,而不是相等操作,可以加上数字来确保有且仅有多少个而不是只要有就行range过滤 可以用于日期范围或时间戳 还可以通过字典顺序来过滤字符串范围
本质上来说,
null
,[]
(空数组)和 [null]
是相等的。它们都不存在于倒排索引中给值为null的指定一个null值 一方面避免为null 另一方面于正常值区别开来
exists过滤器 这个过滤器将返回任何包含这个字段的文档
missing过滤器 它返回没有特定字段值的文档
纯粹地读书,只为好奇心