由于业务需要,查询需求很多,这就导致一个需求就要写一个elasticsearch的java api查询方法,后来无意中发现了一个利用sql进行elasticsearch查询,而且用起来还算比较灵活,在这里分享给大家,如果有不对的地方,欢迎大家指正。
1、首先在项目的pom.xml文件增加jar包
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.3.5</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>delete-by-query</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.nlpcn</groupId>
<artifactId>elasticsearch-sql</artifactId>
<version>2.3.5.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.15</version>
</dependency>
这里需要注意的是elasticsearch和elasticsearch-sql的版本需要一致,否则可能会报有的方法找不到的情况。
2、sql转换的公共方法(我这里的sql用的是mysql格式,其他DB格式还未验证)
/**
* 根据表达式组装ES的query查询语句
*
* @param indexName-索引名
* @param express-查询条件:(f1=2 and f2=1) or (f3=1 and f4=1)
* @return
*/
public static QueryBuilder createQueryBuilderByWhere(String indexName, String whereExpress) {
BoolQueryBuilder boolQuery = null;
try {
String sql = "select * from " + indexName;
String whereTemp = "";
if (StringUtils.isNotBlank(whereExpress)) {
whereTemp = " where " + whereExpress;
}
SQLQueryExpr sqlExpr = (SQLQueryExpr) toSqlExpr(sql + whereTemp);
SqlParser sqlParser = new SqlParser();
MySqlSelectQueryBlock query = (MySqlSelectQueryBlock) sqlExpr.getSubQuery().getQuery();
WhereParser whereParser = new WhereParser(sqlParser, query);
Where where = whereParser.findWhere();
if (where != null) {
boolQuery = QueryMaker.explan(where);
}
} catch (SqlParseException e) {
LOGGER.warn("EsQueryUtil.createQueryBuilderByExpress-Exception", e);
}
return boolQuery;
}
/**
* 验证sql
*
* @param sql sql查询语句
* @return
*/
private static SQLExpr toSqlExpr(String sql) {
SQLExprParser parser = new ElasticSqlExprParser(sql);
SQLExpr expr = parser.expr();
if (parser.getLexer().token() != Token.EOF) {
throw new ParserException("illegal sql expr : " + sql);
}
return expr;
}
3、简单的查询方法
/**
* 查询数据总数
*
* @param indexName 索引名称
* @param whereExpress 查询条件
* @return
*/
public static long searchTotalByApi(String indexName, String whereExpress) {
try {
// 获取Elasticsearch的服务
Client client = EsClientUtil.getEsServer();
// 转换Elasticsearch格式的查询条件
QueryBuilder queryBuilder = createQueryBuilderByWhere(indexName, whereExpress);
// 减少资源消耗,只查询总数
long resultNum = client.prepareSearch(indexName).setQuery(queryBuilder).setFrom(0).setSize(0).execute()
.actionGet().getHits().getTotalHits();
if (0 == resultNum) {
LOGGER.info("EsQueryUtil.seatchTotalByApi-queryBuilder:{}", queryBuilder);
}
return resultNum;
} catch (Exception e) {
LOGGER.warn("EsQueryUtil.seatchTotalByApi-Exception{}", e);
}
return 0;
}