ElasticSearch是目前全文搜索引擎开源组件,功能非常强大,它可以快速地存储、搜索和分析海量数据。ElasticSearch的底层是开源库Lucene,它对Lucene进行封装并提供了REST API的操作接口。ElasticSearch的强大之处就是全文搜索,由于搜索领域涵盖的知识面较广,本文不做展开讨论,主要是探讨一下ElasticSearch的复杂搜索、分页及数据导出的实现。
一、复杂搜索
首先,简单介绍一下bool,它是一种复合查询方式,它是使用一个或多个布尔子句构建的,每个子句都有一个类型化的事件,发生的类型有:
must 查询内容必须出现在匹配的文档中,并将有助于得分;
must_not 查询内容不能出现在匹配的文档中;
filter 查询内容必须出现在匹配的文档中,是对匹配的结果过滤,在过滤器上下文中执行,意味着评分被忽略;
should 查询内容应该出现在匹配的文档中,至少有一个;
即:must必须匹配,filter匹配的结果过滤,should至少有一个,must_not不能匹配。
案例一:搜索同时具有01003001和01002004两个标签的用户。
分析:从需求分析来看,该复合查询的功能比较简单,实现起来也很容易。可通过bool复合查询实现,由两个布尔子句组成,每个子句设置must类型的事件。代码实现如下:
案例二:多组合标签查询,组合标签之间存在并集与交集关系。
分析:采用bool复合查询方式,其组合标签之间的并交集关系描述起来非常困难,而且标签之间的组合条件变化多,很难适应实际的查询分析,从面向对象的封装特征来看,应该封装组合标签之间的条件关系来降低代码耦合。因此,通过freemarker把DSL语句进行模板化,通过代码封装标签之间的条件关系(可变的)并输出DSL语句,把不变的抽象成工具类的方法。
1)不变的DSL查询搜索
2)ftl模板
3)标签之间组合条件关系封装
二、分页查询
ElasticSearch的数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回。分为from-size"浅"分页和scroll"深"分页两种。
1)from-size"浅"分页
查询前面所有的数据,通过截断数据来达到目的。其中,from定义目标数据的偏移量,size定义当前返回的文档数目。通过测试发现:分页的偏移值越大,执行分页查询时间就会越长,并且受到默认index.max_result_window=10000的限制(防止数据量大导致OOM)。
2)scroll"深"分页
相对于from-size的分页来说,使用scroll可以模拟一个传统数据库的cursor,记录当前读取的文档信息位置。这个分页的用法,不是为了实时查询数据,而是为了一次性查询大量的数据(甚至是全部数据)。scroll相当于维护了一份当前索引段的快照信息,在这个查询后的任何新索引进来的数据都不会在这个快照中查询到。使用方法:1、初始化scroll搜索返回scroll_id;2、根据scroll_id读取数据。
通过测试,scroll"深"分页的性能远优于from-size"浅"分页的性能,如果想要对全量数据进行操作(如:数据导出),scroll是一个很好的选择。
领取专属 10元无门槛券
私享最新 技术干货