MOQL除提供从MOQL语法到Oracle、SQL Server、DB2、MySQL、PostgreSQL等SQL方言的语法转换器外,目前还支持了到ElasticSearch语法的转换。转换器的类名字为org.moql.sql.es.ElasticSearchTranslator。由于MOQL是SQL Like的,所以这个转换器可以完成从SQL语法到ElasticSearch查询语法的转换。由于ElasticSearch查询语法的语义与SQL语法语义各有所长,故MOQL只完成了部分二者语义存在交集的语法的转换工作。但该部分转换对于熟悉SQL,又想初步使用ElasticSearch进行查询的开发者已经足够。下面将对该转换器的用法及语法转换关系进行详细的描述。
代码示例
ElasticSearch转换器的使用非常简单,示例代码如下:
public static void main(String[] args) { String sql = "select w.country, max(w.port), min(w.port) from web w group by w.country"; try { //将sql语句串转换为ELASTICSEARCH方言的语法串 String es = MoqlUtils.translateMoql2Dialect(sql, SqlDialectType.ELASTICSEARCH); es = es.trim(); //打印输出转换后的语法串 System.out.println(es); } catch (MoqlException e) { e.printStackTrace(); } } |
以上代码的执行结果如下:
{ "size":0, "aggs":{ "condition":{ "filter":{ "match_all":{} }, "aggs":{ "group":{ "terms":{ "field":"country" }, "aggs":{ "column1":{ "max":{ "field":"port" } }, "column2":{ "min":{ "field":"port" } } } } } } } } |
其它关于转换器的更多说明,可参考文章《MOQL—转换器(Translator)》。关于SQL到ElasticSearch DSL转换的更多示例可参见MOQL源码的org.moql.core.test.TestElasticSearchTranslator.java文件。
语法映射
MOQL转换器不能完整的转换SQL与ElasticSearch的语义,下面将对二者的语义转换关系进行详细的说明。
MOQL |
ElasticSearch |
|
UNION,INTERSECT,EXCEPT等集合操作子句 |
未转换映射 |
|
SELECT子句 |
当MOQL语句中不含DISTINCT和GROUP子句时,映射为ElasticSearch的Filter子句。此时在SELECT子句中指明具体的投影列不起作用,会被统一认为是选择全部列,即SELECT *;而当MOQL含有DISTINCT和GROUP子句时,映射为ElasticSearch的Aggs。此时SELECT子句中的投影列需遵循SQL语法的约定,这样才能正确转换。 |
|
DISTINCT子句 |
转换为ElasticSearch的Aggs子句。 |
|
FROM子句 |
不进行转换 |
|
WHERE子句 |
(注:WHERE子句都被转换为ElasticSearch的Filter子句,但当整个语句中存在GROUP子句时,Filter子句会嵌套在Aggs子句中) |
|
and、or |
映射为and filter和or filter |
|
not、<>(不等于) |
映射为not filter |
|
=(等于) |
映射为term filter |
|
>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、between |
映射为range filter |
|
like |
映射为regexp filter |
|
in |
映射为terms filter |
|
is |
映射为exists filter |
|
用于改变优先级的括号 |
映射为层级关系 |
|
附加部分: regex(field, pattern)函数,用于正则表达式匹配。匹配模式比like更丰富,可参见正则表达式的相关文档。Field参数表示要进行匹配的字段;pattern参数表示匹配串。 |
映射为regexp filter |
|
LIMIT子句 |
映射为ElasticSearch中的size属性。MOQL语句中含有或不含有DISTINCT和GROUP子句,该值会被映射到不同ElasticSearch子句的size属性上。 |
|
ORDER子句 |
当MOQL语句中不含DISTINCT和GROUP子句时,映射为ElasticSearch的sort子句;而当MOQL语句含有以上子句时,映射为Aggs中terms子句的order属性。 |
|
q*() |
ElasticSearch中的Query子句(全文检索)在SQL中没有对应的语法,故该部分语法在MOQL中被设计为了一组前缀为q然后紧跟ElasticSearch对应Query子句名的函数,如:qmatch(…)对应match query子句。目前,MOQL只支持qmatch(field,message)一个函数。field可以是字段名也可以是字符串,当是字段名或字符串中只有一个字段名时转换为match query,如:field1, ’field1’分别是字段名和包含字段名的字符串,均转换为match query;当field为包括多个字段名的字符串,字段名间用’,’号隔开时,转换为multi match query,如:’field1,field2’。 |
MOQL的相关路径如下:
项目地址:http://sourceforge.net/projects/moql/
代码路径:svn://svn.code.sf.net/p/moql/code/trunk