elasticsearch-query-tookit一款基於SQL查詢elasticsearch程式設計工具包,支援SQL解析生成DSL,支援JDBC驅動,支援和Spring、MyBatis整合
阿新 • • 發佈:2018-12-14
`elasticsearch-query-tookit`是一款基於SQL查詢elasticsearch程式設計工具包,支援SQL解析生成DSL,支援JDBC驅動,支援和Spring、MyBatis整合,提供Java程式設計介面可基於此工具包二次開發
只是重新造了個輪子,有興趣的同學可以相互交流,QQ: 465360798
專案地址:https://github.com/gitchennan/ ... olkit
一、SQL解析生成DSL使用示例
SQL語法幫助手冊戳這裡: https://github.com/gitchennan/ ... p-doc
String sql = "select * from index.order where status='SUCCESS' and price > 100 order by nvl(pride, 0) asc routing by 'JD' limit 0, 20"; ElasticSql2DslParser sql2DslParser = new ElasticSql2DslParser(); //解析SQL ElasticSqlParseResult parseResult = sql2DslParser.parse(sql); //生成DSL(可用於rest api呼叫) String dsl = parseResult.toDsl(); //toRequest方法接收一個clinet物件引數 SearchRequestBuilder searchReq = parseResult.toRequest(esClient); //執行查詢 SearchResponse response = searchReq.execute().actionGet();
生成的DSL如下:
{ "from" : 0, "size" : 20, "query" : { "bool" : { "filter" : { "bool" : { "must" : [ { "term" : { "status" : "SUCCESS" } }, { "range" : { "price" : { "from" : 100, "to" : null, "include_lower" : false, "include_upper" : true } } } ] } } } }, "sort" : [ { "pride" : { "order" : "asc", "missing" : 0 } } ] }
二、整合MyBatis、Spring
首先在Spring配置檔案中增加如下程式碼
1. 指定driverClassName:org.elasticsearch.jdbc.api.ElasticDriver
2. 指定連線ES的連線串:jdbc:elastic:192.168.0.109:9300/product_cluster
3. 建立一個SqlMapClient物件,並指定sqlMapConfig.xml路徑
<bean id="elasticDataSource" class="org.elasticsearch.jdbc.api.ElasticSingleConnectionDataSource" destroy-method="destroy">
<property name="driverClassName" value="org.elasticsearch.jdbc.api.ElasticDriver" />
<property name="url" value="jdbc:elastic:192.168.0.109:9300/product_cluster" />
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="elasticDataSource" />
<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
</bean>
sqlMapConfig.xml檔案內容如下:
<sqlMapConfig>
<settings
cacheModelsEnabled="true"
lazyLoadingEnabled="true"
enhancementEnabled="true"
maxSessions="64"
maxTransactions="20"
maxRequests="128"
useStatementNamespaces="true"/>
<sqlMap resource="sqlmap/PRODUCT.xml"/>
</sqlMapConfig>
PRODUCT.xml檔案中宣告select sql語句
<sqlMap namespace="PRODUCT">
<select id="getProductByCodeAndMatchWord" parameterClass="java.util.Map" resultClass="java.lang.String">
SELECT *
FROM index.product
QUERY match(productName, #matchWord#) or prefix(productName, #prefixWord#, 'boost:2.0f')
WHERE productCode = #productCode#
AND advicePrice > #advicePrice#
AND $$buyers.buyerName IN ('china', 'usa')
ROUTING BY #routingVal#
</select>
</sqlMap>
編寫對應DAO程式碼:
@Repository
public class ProductDao {
@Autowired
@Qualifier("sqlMapClient")
private SqlMapClient sqlMapClient;
public List<Product> getProductByCodeAndMatchWord(String matchWord, String productCode) throws SQLException {
Map<String, Object> paramMap = Maps.newHashMap();
paramMap.put("productCode", productCode);
paramMap.put("advicePrice", 1000);
paramMap.put("routingVal", "A");
paramMap.put("matchWord", matchWord);
paramMap.put("prefixWord", matchWord);
String responseGson = (String) sqlMapClient.queryForObject("PRODUCT.getProductByCodeAndMatchWord", paramMap);
//反序列化查詢結果
JdbcSearchResponseResolver responseResolver = new JdbcSearchResponseResolver(responseGson);
JdbcSearchResponse<Product> searchResponse = responseResolver.resolveSearchResponse(Product.class);
return searchResponse.getDocList();
}
}
編寫測試方法
@Test
public void testProductQuery() throws Exception {
BeanFactory factory = new ClassPathXmlApplicationContext("application-context.xml");
ProductDao productDao = factory.getBean(ProductDao.class);
List<Product> productList = productDao.getProductByCodeAndMatchWord("iphone 6s", "IP_6S");
for (Product product : productList) {
System.out.println(product.getProductName());
}
}
-----------------------------------------------
作者:chennanlcy
來源:elastic中文社群