在这里,我想向你们推荐一个我本身开发的项目,也就是elasticsearch-query-builder
,这个项目目前在github上已经开源,有兴趣的朋友能够去fork或者star,你的star就是对我最大的鼓励。同时,本项目长期维护和更新,我也接受而且很高兴有小伙伴向本项目pull request,或者协同开发,有兴趣的同窗能够给我发邮件。git
elasticsearch-query-builder
是一个很是方便构造elasticsearch
(后面简称ES) DSL 查询语句的工具包,在elasticsearch-query-builder
中,我尝试基于配置化的操做去构建ES的查询语句,而且接受外界传入参数,这极大的减小了在Java代码中构建ES查询语句的工做,并同时减小了代码量,使代码更加直观和清晰。基于使ES中DSL构造语句和Java代码分离的思想,elasticsearch-query-builder
诞生了。去GithubFork!github
elasticsearch-query-builder
工程通常做为jar包为别的工程提供使用,固然,若是须要基于本项目作二次开发,这都须要将Github上克隆本项目到本地数据库
1 |
git clone https://github.com/xiaowei1118/elasticsearch-query-builder.git |
在将本项目克隆到本地后,执行mvn package
将本项目打成jar包,或者直接将本项目做为大家本身maven项目的module项目。json
elastcisearch-query-builder接受配置文件(特定json格式)或者json格式的字符串配置,配置格式以下:数组
1 |
{ |
index表示elasticSearch中的索引或者别名。数据结构
type表示elasticSearch索引或者别名下的type。app
from表示检索文档时的偏移量,至关于关系型数据库里的offset。elasticsearch
include_source 搜索结果中包含某些字段,格式为json数组,"include_source": ["name","age"]
。maven
exclude_source 搜索结果中排除某些字段,格式为json数组,"exclude_source":["sex"]
。工具
query_type表示查询类型,支持三种类型terms_level_query
,text_level_query
,bool_level_query
,而且这三种类型
不能够一块儿使用。
terms_level_query
操做的精确字段是存储在反转索引中的。这些查询一般用于结构化数据, 如数字、日期和枚举, 而不是全文字段,包含term_query,terms_query,range_query,exists_query 等类型。
text_level_query
查询一般用于在完整文本字段 (如电子邮件正文) 上运行全文查询。他们了解如何分析被查询的字段, 并在执行以前将每一个字段的分析器 (或 search_analyzer) 应用到查询字符串。
包含 match_query,multi_match_query,query_string,simple_query_string 等类型。
bool_query
与其余查询的布尔组合匹配的文档匹配的查询。bool 查询映射到 Lucene BooleanQuery。它是使用一个或多个布尔子句生成的, 每一个子句都有一个类型化的实例。 布尔查询的查询值包括: must,filter,should,must_not. 想要了解这几个类型的差别,能够查阅elasticSearch的相关文档 在每一个布尔查询的查询类型值中, 能够包含terms_level_query 和 text_level_query中任意的查询类型,如此即可以构造很是复杂的查询状况。
terms_level查询类型,支持term_query
,terms_query
,range_query
,exists_query
查询。
term_query
1 |
"term_query": { |
terms_query
term_query
。 1 |
"terms_query": { |
range_query
,给定的查询条件使一个范围
1 |
"range_query": { |
exists_query
,存在查询,查找字段不存在的文档。
1 |
"exists_query": { |
text_level_query查询类型,支持match_query,multi_match_query,query_string,simple_query_string等。
match_query,普通的文本匹配查询。
1 |
"match_query": { |
multi_match_query 在多个字段中进行文本匹配
1 |
"multi_match_query": { |
query_string 字符串文本匹配。
1 |
"query_string": { |
and
或者 or
。
1 |
"simple_query_string": { |
bool_query是其余查询的布尔组合,通常用于构建复杂的查询,而这正是elasticsearch-query-builder
最拿手的地方。
1 |
"query_type": "bool_query", |
ES的聚合操做一般用于聚合查询结果数据,一般用于数据的分类和统计工做。同时ES自己支持多种聚合操做,为咱们的数据分析和统计提供了便利,相应的,本项目也支持聚合操做的配置化和参数绑定。
1 |
"aggregations": [ |
1 |
{ |
由于aggregation聚合的类型比较多,另外还有,min, max, cardinality,extended_stats, stats,sum,top_hits,value_count,range,missing,date_range,ipv4_range,date_histogram
等,这里就再也不赘述,须要查看聚合类型怎么用的,能够查看配置文件样例
ES能够设置对查询结果中包含搜索关键字的字段部分进行高亮。
<em>
</em>
1 |
"highlight":{ |
单值绑定,这里咱们以sex字段为例,咱们须要查询出index中性别为女性的记录,咱们能够用terms查询,如:
1 |
"term_query": { |
经过以上查询就能够查出性别为女性的文档。那若是咱们的value值须要从外面传进来呢,好比咱们的参数在一个json字符串中(很是适合application/json的传值:)),如:{ "sex": "female",type: 1}
,咱们的配置文件应该怎么写?
在elasticsearch-query-builder
中,咱们约定须要外界绑定的参数用${}
将字段包括进来,如:${sex}
这里的sex
同json数据里面的key一致。那么在配置文件中就转换成了:
1 |
"term_query": { |
若是json中的字段不在第一层呢?比方说:{ "a.sex": "female",type: 1}
, 那么咱们用.
号来表示层级结构,${a.sex}
, 无论层级多深都没有问题。
对于范围类型的参数绑定,好比:type 从 1->6
或者 date 从 2017-06-10 -> 2017-12-12
, 咱们应该怎么从外界进行参数绑定呢?在range查询中,咱们已经定义了range的传参方式,以下:
1 |
"range_query":{ |
其实,其实range的参数绑定和单值的参数绑定是一致的,虽然有范围,其实取的仍是单值${date}
, 只是咱们对外界的json数据结构表示范围的字段有限制,咱们规定json中表示范围的字段必须是[a,b]
的形式,a和b能够单一缺省,表示无上界或者下界,可是a和b不能够同时缺省(同时缺省,这个范围查询是没有意义的)。
如json数据:{ "date": "[2017-06-10, 2017-12-12]" }
即符合规范。
这个例子也是elasticsearch-query-builder
种的example。
咱们先定义配置文件test.json
:
1 |
{ |
使用elasticsearch-query-builder
生成ES的查询语句。
1 |
import com.alibaba.fastjson.JSON; |
生成的ES的DSL查询语句:
1 |
{ |
本项目并无涵盖ES的全部查询功能,同时,也没有包含ES的最新版本的功能,这些都是我后续须要逐渐完善的地方,我但愿能够经过本身的努力,使本项目愈来愈完善。
本项目使用了阿里的fastjson
jar包,elasticsearch公司的elasticsearch
jar包,以及io.searchbox
的jest
jar包,这里表示由衷的感谢。