比如一段 bool 表达式user_id = 1 and (product_id = 1 and (star_num = 4 or star_num = 5) and banned = 1),写成 SQL 是如下形式:
select * from xxx
where user_id = 1 and
(
product_id = 1 and (star_num = 4 or star_num = 5) and banned = 1
)
写成Elasticsearch的 DSL 是如下形式:
{
"query": {
"bool": {
"must": [
{
"match": {
"user_id": {
"query": "1",
"type": "phrase"
}
}
},
{
"match": {
"product_id": {
"query": "1",
"type": "phrase"
}
}
},
{
"bool": {
"should": [
{
"match": {
"star_num": {
"query": "4",
"type": "phrase"
}
}
},
{
"match": {
"star_num": {
"query": "5",
"type": "phrase"
}
}
}
]
}
},
{
"match": {
"banned": {
"query": "1",
"type": "phrase"
}
}
}
]
}
},
"from": 0,
"size": 1
}
Elasticsearch的 DSL 虽然很好理解,但是手写起来非常费劲。前面提供了基于 SDK 的方式来写,但也不足够灵活。
SQL 的 where 部分就是 boolean expression。这种 bool 表达式被解析后,和Elasticsearch的 DSL 结构长得差不多,所以可以直接将 SQL 转换为 DSL。
SQL 的 where 被 parse 之后的结构和Elasticsearch的 DSL 结构对比:
既然结构上完全一致,逻辑上就可以相互转换。以广度优先对 AST 树进行遍历,然后将二元表达式转换成 json 字符串,再拼装起来就可以了,参考:github.com/cch123/elasticsql
最后编辑: kuteng 文档更新时间: 2022-03-22 19:29 作者:kuteng