es的DSL实在是过于难用,相信使用过的同学都会有这种感受。而sql对于99%的程序员来说没有什么学习成本。

所以在工作需要的情况下,完成了这么一个简单的项目:

https://github.com/cch123/elasticsql

把sql转换为es的DSL,这样你就不用每次都去写那个痛苦的DSL了。

这个库可以用来做什么呢?嗯,比如你在业务中用到了es,又不想去为了这套es培训所有人学会es的dsl,那么你可以使用它。再比如你想要实现一个支持sql的es的proxy,也可以把它当成你的一个模块来使用。

当然目前项目还在初期阶段,只实现了取数据部分。就是指定where条件,获取数据这种逻辑。count/sum/min之类的聚会还没有做,回头会加上。

不过where条件的话自我感觉支持还算完美,虽然目前还有点纠结sql里的equal应该用match phrase还是用term来做(因为match phrase要涉及到分词之类的逻辑,会慢一些。而且对于字符串来说,直接用term查询那可能查出来的结果。。就不是你想的那样了。

使用起来很简单:

package main

import (  
    "fmt"

    "github.com/cch123/elasticsql"
)

func main() {  
    dsl, esType, _ := elasticsql.Convert("select * from aaa where a=1 and x = '三个男人' and create_time between '2015-01-01T00:00:00+0800' and '2016-01-01T00:00:00+0800' and process_id > 1 order by id desc limit 100,10")
    fmt.Println(dsl)
    fmt.Println(esType)
}

会输出:

{
    "sort": [
        {
            "id": "desc"
        }
    ],
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "a": {
                            "query": "1",
                            "type": "phrase"
                        }
                    }
                },
                {
                    "match": {
                        "x": {
                            "query": "三个男人",
                            "type": "phrase"
                        }
                    }
                },
                {
                    "range": {
                        "create_time": {
                            "from": "2015-01-01T00:00:00+0800",
                            "to": "2016-01-01T00:00:00+0800"
                        }
                    }
                },
                {
                    "range": {
                        "process_id": {
                            "gt": "1"
                        }
                    }
                }
            ]
        }
    },
    "from": 100,
    "size": 10
}

aaa  

注:为了好看,我把dsl做过prettify了。

上面的查询条件还比较简单,where里带or或者括号什么的也都是可以支持的哦~读者可以自己去试验一下。

局限性嘛,也是有的,现在只能支持单index查询,join的方案我暂时还没想好怎么做。不过既然都用es了,大概大多数人也不会需要用join了吧。。哈哈

欢迎来github提issue(tucao

当然了,和这个项目同质的项目也是有的,比如elasticsearch-sql,是作为es的插件存在,而我们公司的大大做的es-monitor,作为python程序实现了类似的功能。那为什么我们还需要一个golang版?

因为代码洁癖。

以上。