重启elasticsearchh聚合以后只能获取到聚合字段的值么

以下测试集群中两个机器都单独存储数据

  1. 在重启elasticsearchh1.6版本下尝试多次后发现,当集群一开始只有一个时即另一个并没有启动(两个机器的node.master都是默认值,也就是true)插叺数据,并进行聚类运算是正常的当启动集群中另一个机器时,由于es会自动复制数据复制完数据后,再进行聚类查询结果错误
  2. 在偅启elasticsearchh1.6版本下集群中的两台机器均启动,此时集群中没有数据创建mapping并插入数据。再次进行查询结果正确
  3. 在重启elasticsearchh1.6版本下集群中一台機器设置node.master: true,另一个设置为 false先对master机器进行数据插入后,再启动slave机器进行自动数据复制再次进行查询,结果错误
  4. 在重启elasticsearchh1.7版本下,进行了哃样的测试每一次结果都和1.6版本相同。

  1. 由于会出现类型转换错误但是普通查询并没有出错。猜测是由于重启elasticsearchh在集群中两台机器都鈳以是master的情况下导致mapping同步问题而数据本身没错。

如果要两个都是master则需要在集群正常的情况下进行mapping的创建,数据的插入等等避免出错。

我觉得可能也和我的数据有原因吧但是就算是数据有问题,索引本身mapping也不应该出错。这里应该是重启elasticsearchh有一些问题导致一下子我并鈈能从核心来解决这个问题。只能是在集群中一定要正确使用。

还有一种查询方式用脚本查询

最后还有一种方法,由于我的字段是long类型的而且有很多这样的字段,却只有一个字段有问题解决方法很简单,把这个字段修改成万能的string类型就能解决问题。至于到底是什麼原因导致的问题我在看源码,但是并不能一下子就搞定。稍等……

}

基于es 5.4和es 5.6列举的是个人工作中经瑺用到的查询(只是工作中使用的是Java API),如果需要看完整的可以参考官方相关文档

先使用一个快速入门来引入,然后后面列出的各种查詢都是用得比较多的(在我的工作环境是这样)其它没怎么用的这里就不列出了。

1.1.3 包含指定字段(以term为例)

查询字段会被索引和分析茬执行之前将每个字段的分词器(或搜索分词器)应用于查询字符串。

operator默认是or也就是说,“里皮恒大”被分词为“里皮”和“恒大”呮要content中出现两个之一,都会搜索到;设置为and之后只有同时出现都会被搜索到。

文档同时满足下面两个条件才会被搜索到:

  • (1)分词后所囿词项都要出现在该字段中
  • (2)字段中的词项顺序要一致

词项搜索时对倒排索引中存储的词项进行精确匹配词项级别的查询通过用于结構化数据,如数字、日期和枚举类型

term的升级版,如上面查询的postdate字段可以设置多个。

因为term是精确匹配所以不要问,[]中的关系怎么设置and这怎么可能,既然是精确匹配一个字段也不可能有两个不同的值。

匹配某一范围内的数据型、日期类型或者字符串型字段的文档注意只能查询一个字段,不能作用在多个字段上

gt:大于,gte:大于等于lt:小于,lte:小于等于

format不加也行如果写的时间格式正确。

返回对应芓段中至少有一个非空值的文档也就是说,该字段有值(待会会说明这个概念)

以下文档会匹配上面的查询:

有user字段,且不为空
有user字段值为空字符串
有user字段,值不为空
有user字段值不为空
有user字段,至少一个值不为空即可

下面的文档不会被匹配:

虽然有user字段但是值为空
雖然有user字段,但是值为空
虽然有user字段但是值为空

查询具有指定id的文档。

类型是可选的也可以以数据的方式指定多个id。

因为工作中接触箌关于es是做聚合、统计、分类的项目经常要做各种复杂的多条件查询,所以实际上bool query用得非常多,因为查询条件个数不定所以处理的邏辑思路时,外层用一个大的bool query来进行承载(当然,项目中是使用其Java API)

bool query可以组合任意多个简单查询各个简单查询之间的逻辑表示如下:

攵档必须匹配must选项下的查询条件,相当于逻辑运算的AND
文档可以匹配should选项下的查询条件也可以不匹配,相当于逻辑运算的OR
与must相反匹配该選项下的查询条件的文档不会被返回
和must一样,匹配filter选项下的查询条件的文档才会被返回但是filter不评分,只起到过滤功能

如果希望有多个must时比如希望同时匹配"里皮"和"中超",但是又故意分开这两个关键词(因为事实上一个must,然后使用match并且operator为and就可以达到目的),怎么操作紸意must下使用数组,然后里面多个match对象就可以了:

当然must下的数组也可以是多个bool查询条件以进行更加复杂的查询。

1.6 补充:数组查询与测试

Note1:紸意设置字段类型时keywords设置为keyword,所以使用term查询可以精确匹配但设置为text,则不一定——如果有添加分词器则可以搜索到;如果没有,而昰使用默认的分词器只是将其分为一个一个的字,就不会被搜索到这点尤其需要注意到。

Note2:对于数组字段也是可以做桶聚合的,做桶聚合的时候其每一个值都会作为一个值去进行分组,而不是整个数组进行分组可以使用上面的进行测试,不过需要注意的是其字段类型不能为text,否则聚合会失败

Note3:所以根据上面的提示,一般纯数组比较适合存放标签类的数据就像上面的案例一样,同时字段类型設置为keyword而不是text,搜索时进行精确匹配就好了

如果一次性要查出来比如10万条数据,那么性能会很差此时一般会采取用scoll滚动查询,一批┅批的查直到所有数据都查询完处理完(es返回的scrollId,可以理解为是es进行此次查询的操作句柄标识每发送一次该scrollId,es都会操作一次或者说循环一次,直到时间窗口到期)

使用scoll滚动搜索,可以先搜索一批数据然后下次再搜索一批数据,以此类推直到搜索出全部的数据来,scoll搜索会在第一次搜索的时候保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索如果这个期间数据变更,是不会讓用户看到的每次发送scroll请求,我们还需要指定一个scoll参数指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了(也僦是说该scrollId只在这个时间窗口内有效,视图快照也是)

相当于MySQL的聚合函数。

size不设置为0除了返回聚合结果外,还会返回其它所有的数据

相当于MySQL的group by操作,所以不要尝试对es中text的字段进行桶聚合否则会失败。

相当于分组查询根据字段做聚合。

在桶聚合的过程中还可以进行指标聚合相当于mysql做group by之后,再做各种max、min、avg、sum、stats之类的:

上面的聚合操作相当于是:查询gender为1的各个指标

在Filter的基础上,可以查询多个字段各洎独立的各个指标即对每个查询结果分别做指标聚合。

to:小于from:大于等于

跟上面一个类似的,其实只是字段为日期类型的然后范围徝也是日期。

这个功能十分有用可以根据年月日来对数据进行分类。

这样聚合的话包含的年份的每一个月的数据都会被分类,不管其昰否包含文档

这样聚合的话,包含的年份的每一个月的每一天的数据都会被分类不管其是否包含文档。

}

之前总结过metric聚合的内容本篇来說一下bucket聚合的知识。Bucket可以理解为一个桶他会遍历文档中的内容,凡是符合要求的就放入按照要求创建的桶中

本篇着重讲解的terms聚合,它昰按照某个字段中的值来分类:

比如性别有男、女就会创建两个桶,分别存放男女的信息默认会搜集doc_count的信息,即记录有多少男生有哆少女生,然后返回给客户端这样就完成了一个terms得统计。

使用terms聚合结果可能带有一定的偏差与错误性。

我们想要获取name字段中出现频率朂高的前5个

此时,客户端向ES发送聚合请求主节点接收到请求后,会向每个独立的分片发送该请求
分片独立的计算自己分片上的前5个name,然后返回当所有的分片结果都返回后,在主节点进行结果的合并再求出频率最高的前5个,返回给客户端

这样就会造成一定的误差,比如最后返回的前5个中有一个叫A的,有50个文档;B有49 但是由于每个分片独立的保存信息,信息的分布也是不确定的 有可能第一个分爿中B的信息有2个,但是没有排到前5所以没有在最后合并的结果中出现。 这就导致B的总数少计算了2本来可能排到第一位,却排到了A的后媔

为了改善上面的问题,就可以使用size和shard_size参数

  • size参数规定了最后返回的term个数(默认是10个)
  • shard_size参数规定了每个分片上返回的个数
  • 如果shard_size小于size,那么分爿也会按照size指定的个数计算

通过这两个参数如果我们想要返回前5个,size=5;shard_size可以设置大于5这样每个分片返回的词条信息就会增多,相应的误差几率也会减小

order指定了最后返回结果的排序方式,默认是按照doc_count排序

也可以按照字典方式排序:

当然也可以通过order指定一个单值的metric聚合,来排序

同时也支持多值的Metric聚合,不过要指定使用的多值字段:

聚合的字段可能存在一些频率很低的词条如果这些词条数目比例很大,那麼就会造成很多不必要的计算
因此可以通过设置min_doc_count和shard_min_doc_count来规定最小的文档数目,只有满足这个参数要求的个数的词条才会被记录返回

桶聚匼也支持脚本的使用:

filter字段提供了过滤的功能,使用两种方式:include可以过滤出包含该值的文档;相反则使用exclude

上面的例子中,最后的结果应該包含sport并且不包含water
也支持数组的方式,定义包含与排除的信息:

通常情况terms聚合都是仅针对于一个字段的聚合。因为该聚合是需要把词條放入一个哈希表中如果多个字段就会造成n^2的内存消耗。

不过对于多字段,ES也提供了下面两种方式:

  • 2 使用copy_to方法合并两个字段,创建絀一个新的字段对新字段执行单个字段的聚合。

对于子聚合的计算有两种方式:

  • breadth_first 先计算出当前聚合的结果,针对这个结果在对子聚合進行计算

默认情况下ES会使用深度优先,不过可以手动设置成广度优先比如:

缺省值指定了缺省的字段的处理方式:

}

我要回帖

更多关于 重启elasticsearch 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信