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_scorestrue
字段值默认以顺序排列,而 _score 默认以倒序排列
对于集合, 可以使用min, max, avgsum这些模式在集合中选出一个想要作为排序的比较
 
 
相关性计算
检索词频率
出现频率越高,相关性也越高。 字段中出现过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: <= 小于或等于
termterms包含操作,而不是相等操作,可以加上数字来确保有且仅有多少个而不是只要有就行
range过滤  可以用于日期范围或时间戳  还可以通过字典顺序来过滤字符串范围
 
本质上来说,null[](空数组)和 [null] 是相等的。它们都不存在于倒排索引中
给值为null的指定一个null值  一方面避免为null   另一方面于正常值区别开来
 
exists过滤器             这个过滤器将返回任何包含这个字段的文档
missing过滤器          它返回没有特定字段值的文档
posted on 2017-09-06 15:31  一个人的合唱  阅读(193)  评论(0编辑  收藏  举报