sql >> Databáze >  >> NoSQL >> MongoDB

Analyzujte sql dotaz pomocí antlr parsetree to mongo bson dokumentu v Javě

V jedné ze svých předchozích zakázek jsem udělal něco podobného:dostal jsem dotaz (ne sql, ale dost podobný) a přeložil ho do mongo dotazu pomocí antlr.

Nemám kód ke sdílení, ale mohu se podělit o své myšlenky:

  1. Mongo není kompatibilní s SQL, takže si nemůžete vzít pouze sql gramatiku. A co JOINy ​​a celá relační algebra? A co agregace, které jsou v mongu dost složité se svým agregačním rámcem? V opačném směru, jak vygenerujete SQL, který se přeloží do klauzule „existuje“ v mongo. Existuje mnoho takových věcí, některé jsou malé, některé jsou obrovské, ale sečteno a podtrženo, musíte mluvit o nějaké podmnožině SQL, nějaké DSL, které je povoleno používat jako dotazovací jazyk a vypadá „jako“ sql, protože lidé jsou zvyklí na SQL.

  2. S ohledem na to byste si měli vytvořit svou vlastní gramatiku a Antlr vám vygeneruje lexer/analyzátor. Samozřejmostí je také kontrola syntaxe dotazu v Runtime. Antlr nebude schopen analyzovat dotaz, pokud není ve správném formátu, některé gramatické pravidlo selže. To je další důvod, proč nebrat SQL "jak je".

  3. Zatím je to v pořádku, vytvořili jste si vlastního posluchače/návštěvníka. V mém případě jsem se rozhodl pro vytvoření objektové reprezentace dotazu s vnitřním stavem a vším. Takže dotaz

Select id,name 
from employee 
where age > 30 
 and department = 'IT' 
limit 200

Byl přeložen na objekty typu:


class Query {
   private SelectClause select;
   private FromClause  from;
   private WhereClause where;
   private Limit        limit;
}

class SelectClause {
   private List<String> fields;
}
...
class WhereClause {
   Condition root;
}

interface Condition {
...
}

class AndCondition implements Condition { // the same for Not, Or

}

Pro tento konkrétní dotaz je to něco jako:

Query q = new Query(new SelectClause(["id", "name"]), new FromClause("employee"), new WhereClause(new AndCondition(new SimpleLeafCondition("age", Operators.GT, 30), new  SimpleLeafCondition("department", Operators.EQ, "IT" )), new Limit(30));

Pak je možné v dotazu provést určité optimalizace (jako je vložení klauzulí where, pokud potřebujete, nebo například manipulace s částí „Pro“, pokud pracujete v prostředí s více nájemci a máte různé kolekce pro různé tenanty).

Koneckonců, můžete použít návrhový vzor "interpret" a rekurzivně analyzovat objekty dotazu a "přeložit" je do platného mongo dotazu. Pamatuji si, že tento krok mi zabral něco jako 1 den (bylo to před 7 lety s mongo 2 I hádejte, ale přesto), vzhledem ke správné struktuře objektů reprezentujících dotaz, by to nemělo být tak složité. Uvádím to, protože to vypadá, že je to váš hlavní zájem v otázce.




  1. Najděte dokumenty, které obsahují určitá pole pro dílčí objekt MongoDb a Node.js

  2. Databáze k výběru pro hru

  3. Časový limit nastal po 30 000 ms při výběru serveru pomocí CompositeServerSelector

  4. Vnořený dotaz MongoDB vrací pouze poslední vyskytující se výsledek