Wir erstellen unsere eigene Abfragesprache ähnlich wie MySQL mit antlr4. Außer wir verwenden nur where clause
, mit anderen Worten, der Benutzer gibt keine select/from
Anweisungen ein.
Ich konnte Grammatik dafür erstellen und Lexer / Parser / Listener in Golang generieren.
Unter unserer Grammatikdatei 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
;
...
Abfragebeispiel: color="red" and price=20000 or model="hyundai" and (seats=4 or year=2001)
ElasticSearch unterstützt SQL-Abfragen mit Plugin hier: https://github.com/elastic/elasticsearch/tree/master/x-pack/plugin/sql .
Es fällt mir schwer, Java-Code zu verstehen.
Da wir logische Operatoren haben, bin ich mir nicht sicher, wie ich den Analysebaum abrufen und in eine ES-Abfrage konvertieren soll. Kann jemand helfen / Ideen vorschlagen?
Update 1: Weitere Beispiele mit entsprechender ES-Abfrage hinzugefügt
Abfragebeispiel 1: color="red" AND price=2000
ES-Abfrage 1:
{
"query": {
"bool": {
"must": [
{
"terms": {
"color": [
"red"
]
}
},
{
"terms": {
"price": [
2000
]
}
}
]
}
},
"size": 100
}
Abfragebeispiel 2: color="red" AND price=2000 AND (model="hyundai" OR model="bmw")
ES-Abfrage 2:
{
"query": {
"bool": {
"must": [
{
"bool": {
"must": {
"terms": {
"color": ["red"]
}
}
}
},
{
"bool": {
"must": {
"terms": {
"price": [2000]
}
}
}
},
{
"bool": {
"should": [
{
"term": {
"model": "hyundai"
}
},
{
"term": {
"region": "bmw"
}
}
]
}
}
]
}
},
"size": 100
}
Abfragebeispiel 3: color="red" OR color="blue"
ES-Abfrage 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
in der ES-Syntax aus? Sie möchten die JSON-Syntax oder die Syntax für kurze Abfragezeichenfolgen oder etwas ganz anderes? Es ist auch hilfreich, wenn Sie mehr als ein Beispiel hinzufügen. Haben Sie auch schon selbst etwas ausprobiert?Antworten:
Arbeitsdemo-URL: https://github.com/omurbekjk/convert-dsl-to-es-query-with-antlr , geschätzte aufgewendete Zeit: ~ 3 Wochen
Nachdem ich antlr4 und einige Beispiele untersucht hatte, fand ich eine einfache Lösung mit Listener und Stack. Ähnlich wie Ausdrücke mit Stack berechnet werden.
Wir müssen den Standard-Basis-Listener mit unserem überschreiben, um Trigger für jede Grammatikregel zum Eingeben / Beenden zu erhalten. Wichtige Regeln sind:
Unten mein in Golang geschriebener benutzerdefinierter Listener-Code:
Und Hauptdatei:
quelle
Haben Sie sich Gedanken über Ihre SQL-ähnliche Aussagen zu konvertieren Query - String - Abfragen ?
Wenn Ihre Anwendungsfälle so einfach bleiben
color="red" and price=20000 or model="hyundai" and (seats=4 or year=2001)
, würde ich mich an die oben genannten Punkte halten. Die Syntax ist recht leistungsfähig, aber die Abfragen werden garantiert langsamer ausgeführt als die nativen, buchstabierten DSL-Abfragen, da der ES-Parser sie für Sie in DSL konvertieren muss.quelle
GET index_name/_mapping
möchten Sie zuerst Ihre Zuordnung abrufen ( ) und ermitteln, welche Felder den Benutzern zur Suche zur Verfügung gestellt werden sollen (damit Sie Ihren Validator oder eine "Did-You-Mean" -Funktionalität erstellen können). Wenn Sie die Feldwertdatentypen erzwingenEs gibt eine Software namens Dremio https://www.dremio.com/
Es kann SQL-Abfragen in elastische Suchabfragen übersetzen
https://www.dremio.com/tutorials/unlocking-sql-on-elasticsearch/
quelle