Java API利用SQL查询Elasticsearch

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

 

 

猜你喜欢

转载自shilaike.iteye.com/blog/2395712