由于业务需要,查询需求很多,这就导致一个需求就要写一个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; }