引入依赖:
application.properties 配置文件:
连接配置:
2、API操作ES 2.1 查询索引列表可以模糊匹配索引名称
2.2 TermsQueryes 的 trem query 做的是精确匹配查询,关于这里早 serviceName 字段后面加的 .keyword 说明如下:
1.es5.0 及以后的版本取消了 String 类型,将原先的 String 类型拆分为 text 和 keyword 两种类型。它们的区别在于 text 会对字段进行分词处理而 keyword 则不会。
2.当没有为索引字段预先指定 mapping 的话,es 就会使用 Dynamic Mapping ,通过推断你传入的文档中字段的值对字段进行动态映射。例如传入的文档中字段 total 的值为12,那么 total 将被映射为 long 类型;字段 addr 的值为"192.168.0.1",那么 addr 将被映射为 ip 类型。然而对于不满足 ip 和 long 格式的普通字符串来说,情况有些不同:ES 会将它们映射为 text 类型,但为了保留对这些字段做精确查询以及聚合的能力,又同时对它们做了 keyword 类型的映射,作为该字段的 fields 属性写到 _mapping 中。例如,我这里使用的字段 “serviceName”,用来存储服务名称字符串类型,会对它做如下的 Dynamic Mapping:
在之后的查询中使用 serviceName 是将 serviceName 作为 text 类型查询,而使用 serviceName.keyword 则是将 serviceName 作为 keyword 类型查询。前者会对查询内容做分词处理之后再匹配,而后者则是直接对查询结果做精确匹配。
3.es 的 trem query 做的是精确匹配而不是分词查询,因此对 text 类型的字段做 term 查询将是查不到结果的(除非字段本身经过分词器处理后不变,未被转换或分词)。此时,必须使用 serviceName.keyword 来对 serviceName 字段以 keyword 类型进行精确匹配。
Java API
2.3 WildcardQueryes的 wildcard query 做的是模糊匹配查询,类似 sql 中的 like,而 value 值前后的 “*” 号类似与 sql 中的 ”%“ 。
Java API
2.4 RangeQueryes 的 range query 做的是范围查询,相当于 sql 中的 between … and …
Java API
2.5 MatchQueryes的 match query 做的是全文检索,会对关键字进行分词后匹配词条。
query:搜索的关键字,对于英文关键字如果有多个单词则中间要用半角逗号分隔,而对于中文关键字中间可以用逗号分隔也可以不用。
Java API
2.6 MultiMatchQuery上面的 MatchQuery 有一个短板,假如用户输入了某关键字,我们在检索的时候不知道具体是哪一个字段,这时我们用什么都不合适,而 MultiMatchQuery 的出现解决了这个问题,他可以通过 fields 属性来设置多个域联合查找,具体用法如下
Java API
2.7 ExistsQueryes的 exists query 做的是检索某个字段存在的数据,即不为 null 的数据。其中指定的 field 可以是一个具体的字段,也可以是一个 json 结构。
Java API
2.8 BoolQueryes的 bool query 做的是将多个查询组合起来去检索数据,主要的组合参数有 must、should、mustNot 等。
must:数据必须匹配 must 所包含的查询条件,相当于 ”AND“should:数据匹配 should 包含的一个或多个查询条件,相当于 ”OR“mustNot:数据必须不匹配 mustNot 所包含的查询条件,相当于 ”NOT“Java API
2.9 排序es 使用 sort 进行排序,可以多个字段联合排序。
先按照第一个字段排序,第一个字段相同时按照第二个字段排序。
Java API
2.10 结果字段过滤检索数据,有时只需要其中的几个字段,es 也支持对结果集进行字段筛选过滤。字段可以使用 “*” 进行模糊匹配。
Java API
2.11 分页es 的分页方式有三种:from+ size、scroll、search_after, 默认采用的分页方式是 from+ size 的形式。
2.11.1 from+ size
通过查询结果可以发现,我们设置了分页参数之后, hits.total 返回的是数据总数7149,而按照分页规则,我们设置的size=2,因此 hits.hits 里面只有两条数据。
Java API
2.11.2 scroll
一种可满足深度分页的方式,es 提供了 scroll 的方式进行分页读取。原理上是对某次查询生成一个游标 scroll_id , 后续的查询只需要根据这个游标去取数据,每次只能拿到下一页的数据,直到结果集中返回的 hits 字段为空,就表示遍历结束。这里scroll=1m是scroll_id的有效期,表示1分钟,过期后会被es自动清理,每次查询会更新此值。
后续的查询中查询条件不需要指定,只需要携带 scroll_id 即可它会按照首次查询条件进行分页展示,下一次查询(两种方式):
Java API
2.11.3 search_after
search_after 是 ES5.0 及之后版本提供的新特性,search_after查询时需要指定sort排序字段,可以指定多个排序字段,后续查询有点类似 scroll ,但是和 scroll 又不一样,它提供一个活动的游标,通过上一次查询的最后一条数据的来进行下一次查询。 这里需要说明一下,使用search_after查询需要将from设置为0或-1,当然你也可以不写
第一次查询:
查询结果:可以看到每一条数据都有一个sort部分,而下一页的查询需要本次查询结果最后一条的sort值作为游标,实现分页查询
第二次查询:
Java API
2.11.4 三种分页方式特点
from+size 比较适合浅分页模式,在深度分页的情况下,这种使用方式效率是非常低的,随着分页页码的不断增大,查询的效率会直线下降。比如from = 5000, size=20, es 需要在各个分片上匹配排序并得到5000*20 条有效数据,然后在结果集中取最后20条。除了效率上的问题,还有一个无法解决的问题是,es 目前支持最大的 skip 值是 max_result_window ,默认为 10000 。也就是当 from + size > max_result_window 时,es 将返回错误。scroll 是一种滚屏形式的分页检索,满足深度分页的场景。查询的时候生成一个游标 scroll_id,有效期内每次返回的值是一样的,后续的查询只需要根据这个游标去取数据即可。scroll查询是很耗性能的方式,scroll_id 的生成可以理解为建立了一个临时的历史快照, 系统会耗费大量的资源来保存一份当前查询结果集映像,并且会占用文件描述符,在此之后的增删改查等操作不会影响到这个快照的结果,因此不建议在实时查询中运用。这种方式往往用于非实时处理大量数据的情况,比如要进行数据迁移或者索引变更之类的。search_after 适用于深度分页+ 排序,分页是根据上一页最后一条数据来定位下一页的位置,所以无法跳页请求,同时在分页请求的过程中,如果有索引数据的增删改,这些变更也会实时的反映到游标上。在选择search_after的排序字段时尽量使用比如文档的id或者时间戳等具有唯一性的字段。search_after 相比 from+size 的浅分页以及 scroll 滚屏查询会有很大的性能提升。 2.22 聚合es 的 aggs 对数据进行聚合查询统计,查询方式如下:
Java API
多层嵌套聚合
Java API
聚合查询还提供了许多查询规则,按时间date聚合、count聚合、avg聚合、sum聚合、min聚合、max聚合等等,这里就不一一列举了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持七叶笔记。