sql >> Base de Datos >  >> NoSQL >> MongoDB

Analizar la consulta sql usando antlr parsetree para el documento mongo bson en Java

En uno de mis trabajos anteriores hice algo similar:obtuve una consulta (no un sql, pero bastante similar) y la traduje a consulta mongo con antlr.

No tengo un código para compartir. Sin embargo, puedo compartir mis pensamientos:

  1. Mongo no es compatible con SQL, por lo que no puede simplemente tomar una gramática sql. ¿Qué pasa con JOINs y todo el álgebra relacional? ¿Qué pasa con las agregaciones que son bastante complicadas en mongo con su marco de agregación? En la dirección opuesta, ¿cómo genera SQL que se traduce a la cláusula "existe" en mongo? Hay muchas cosas como esta, algunas son pequeñas, otras son enormes, pero en resumen, debe estar hablando de algún tipo de subconjunto de sql, algún DSL que se permite usar como lenguaje de consulta y se ve "como" un sql porque la gente está acostumbrada a SQL.

  2. Con eso en mente, debe crear su propia gramática y Antlr generará un lexer/parser para usted. También obtendrá una verificación de sintaxis de la consulta en Runtime. Antlr no podrá analizar la consulta si no está en un formato correcto, obviamente, alguna regla gramatical fallará. Esta es otra razón para no tomar SQL "tal cual".

  3. Hasta aquí todo bien, has creado tu propio oyente/visitante. En mi caso he optado por crear una representación de objeto de la consulta con estado interno y todo. Así que la consulta

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

Fue traducido a objetos de tipo:


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

}

Para esta consulta en particular es algo como:

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));

Luego, es posible realizar algunas optimizaciones en la consulta (como incrustar cláusulas where si lo necesita o, por ejemplo, manipular la parte "Para" si está trabajando en un entorno de múltiples inquilinos y tiene diferentes colecciones para diferentes inquilinos).

Después de todo, puede ir con el patrón de diseño "intérprete" y analizar recursivamente los objetos de consulta y "traducirlos" a una consulta mongo válida. supongo, pero aún así), dada la estructura correcta de los objetos que representan la consulta, por lo que esto no debería ser tan complicado. Menciono esto porque parece que es su principal preocupación en la pregunta.