Мы создаем наш собственный язык запросов, аналогичный Mysql, используя antlr4. За исключением того, что мы используем только where clause
, другими словами, пользователь не вводит select/from
операторов.
Я смог создать для него грамматику и сгенерировать лексеры / парсеры / слушатели в golang.
Ниже нашего файла грамматики EsDslQuery.g4:
grammar EsDslQuery;
options {
language = Go;
}
query
: leftBracket = '(' query rightBracket = ')' #bracketExp
| leftQuery=query op=OR rightQuery=query #orLogicalExp
| leftQuery=query op=AND rightQuery=query #andLogicalExp
| propertyName=attrPath op=COMPARISON_OPERATOR propertyValue=attrValue #compareExp
;
attrPath
: ATTRNAME ('.' attrPath)?
;
fragment ATTR_NAME_CHAR
: '-' | '_' | ':' | DIGIT | ALPHA
;
fragment DIGIT
: ('0'..'9')
;
fragment ALPHA
: ( 'A'..'Z' | 'a'..'z' )
;
attrValue
: BOOLEAN #boolean
| NULL #null
| STRING #string
| DOUBLE #double
| '-'? INT EXP? #long
;
...
Пример запроса: color="red" and price=20000 or model="hyundai" and (seats=4 or year=2001)
ElasticSearch поддерживает sql запросов с плагином здесь: https://github.com/elastic/elasticsearch/tree/master/x-pack/plugin/sql .
Трудно понять код java.
Поскольку у нас есть логические операторы, я не совсем уверен, как получить дерево разбора и преобразовать его в запрос ES. Может кто-нибудь помочь / предложить идеи?
Обновление 1: добавлено больше примеров с соответствующим запросом ES
Пример запроса 1: color="red" AND price=2000
Запрос ES 1:
{
"query": {
"bool": {
"must": [
{
"terms": {
"color": [
"red"
]
}
},
{
"terms": {
"price": [
2000
]
}
}
]
}
},
"size": 100
}
Пример запроса 2: color="red" AND price=2000 AND (model="hyundai" OR model="bmw")
Запрос ES 2:
{
"query": {
"bool": {
"must": [
{
"bool": {
"must": {
"terms": {
"color": ["red"]
}
}
}
},
{
"bool": {
"must": {
"terms": {
"price": [2000]
}
}
}
},
{
"bool": {
"should": [
{
"term": {
"model": "hyundai"
}
},
{
"term": {
"region": "bmw"
}
}
]
}
}
]
}
},
"size": 100
}
Пример запроса 3: color="red" OR color="blue"
ES запрос 3:
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": {
"terms": {
"color": ["red"]
}
}
}
},
{
"bool": {
"must": {
"terms": {
"color": ["blue"]
}
}
}
}
]
}
},
"size": 100
}