Estamos construindo nossa própria linguagem de consulta semelhante ao Mysql usando antlr4. Exceto que usamos apenas where clause
, em outras palavras, o usuário não insere select/from
instruções.
Eu era capaz de criar gramática e gerar lexers / parsers / listeners em golang.
Abaixo do nosso arquivo gramatical 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
;
...
Exemplo de consulta: color="red" and price=20000 or model="hyundai" and (seats=4 or year=2001)
O ElasticSearch suporta consultas sql com plug-in aqui: https://github.com/elastic/elasticsearch/tree/master/x-pack/plugin/sql .
Tendo dificuldade para entender o código java.
Como temos operadores lógicos, não tenho certeza de como obter a árvore de análise e convertê-la em consulta ES. Alguém pode ajudar / sugerir idéias?
Atualização 1: Adicionado mais exemplos com a consulta ES correspondente
Exemplo de consulta 1: color="red" AND price=2000
Consulta ES 1:
{
"query": {
"bool": {
"must": [
{
"terms": {
"color": [
"red"
]
}
},
{
"terms": {
"price": [
2000
]
}
}
]
}
},
"size": 100
}
Exemplo de consulta 2: color="red" AND price=2000 AND (model="hyundai" OR model="bmw")
Consulta 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
}
Exemplo de consulta 3: color="red" OR color="blue"
Consulta ES 3:
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": {
"terms": {
"color": ["red"]
}
}
}
},
{
"bool": {
"must": {
"terms": {
"color": ["blue"]
}
}
}
}
]
}
},
"size": 100
}
color="red" and price=20000 or model="hyundai" and (seats=4 or year=2001
sintaxe do ES? Você quer a sintaxe JSON, a sintaxe curta da cadeia de caracteres de consulta ou algo completamente diferente? Também ajuda se você adicionar mais de 1 exemplo. Além disso, você já tentou alguma coisa?Respostas:
URL da demonstração de trabalho: https://github.com/omurbekjk/convert-dsl-to-es-query-with-antlr , tempo estimado gasto: ~ 3 semanas
Depois de investigar o antlr4 e vários exemplos, encontrei uma solução simples com ouvinte e pilha. Semelhante a como as expressões são calculadas usando a pilha.
Precisamos substituir o ouvinte base padrão pelo nosso para obter gatilhos para cada regra de gramática de entrada / saída. Regras importantes são:
Abaixo do meu código de ouvinte personalizado, escrito em golang:
E arquivo principal:
fonte
Você já pensou em converter suas instruções do tipo sql em consultas de string ?
Se seus casos de uso continuarem simples
color="red" and price=20000 or model="hyundai" and (seats=4 or year=2001)
, eu usaria o que foi dito acima. A sintaxe é bastante poderosa, mas é garantido que as consultas são executadas mais lentamente do que as consultas DSL nativas e detalhadas, pois o analisador ES precisará convertê-las em DSL para você.fonte
GET index_name/_mapping
), identificar quais campos você deseja expor aos usuários para pesquisar (para poder criar seu validador ou uma funcionalidade "você quis dizer"). Se você deseja aplicar os tipos de dados do valor do campo, também pode extrair essas informações do mapeamento ...Existe um software chamado Dremio https://www.dremio.com/
Pode traduzir consulta SQL para consulta de pesquisa elástica
https://www.dremio.com/tutorials/unlocking-sql-on-elasticsearch/
fonte