Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用antlr parsetree解析sql查询到Java中的mongo bson文档_Java_Mongodb_Antlr4_Mongo Java_Mongo Java Driver - Fatal编程技术网

使用antlr parsetree解析sql查询到Java中的mongo bson文档

使用antlr parsetree解析sql查询到Java中的mongo bson文档,java,mongodb,antlr4,mongo-java,mongo-java-driver,Java,Mongodb,Antlr4,Mongo Java,Mongo Java Driver,我有一个类似SQL的查询示例: Select id,name from employee where age > 30 and department = 'IT' limit 200 SQL查询语法是在ANTLR4语法文件中定义的。是否有任何实现将此查询的解析树转换为bson文档 然后,bson文档将用于查询mongo db。在我以前的一项工作中,我做了类似的事情:获取一个查询(不是sql,但非常类似),并使用antlr将其转换为mongo查询 我没有代码可供分享,但我可以分享我的想法:

我有一个类似SQL的查询示例:

Select id,name from employee where age > 30 and department = 'IT' limit 200
SQL查询语法是在ANTLR4语法文件中定义的。是否有任何实现将此查询的解析树转换为bson文档


然后,bson文档将用于查询mongo db。

在我以前的一项工作中,我做了类似的事情:获取一个查询(不是sql,但非常类似),并使用antlr将其转换为mongo查询

我没有代码可供分享,但我可以分享我的想法:

  • Mongo不符合SQL,所以不能只接受SQL语法。连接和所有的关系代数呢?在mongo中使用聚合框架非常棘手的聚合怎么办?相反,如何生成在mongo中转换为“exists”子句的SQL。有很多类似的东西,有些很小,有些很大,但归根结底,你必须谈论的是某种sql子集,一些DSL被允许用作查询语言,看起来“像”sql,因为人们已经习惯了sql

  • 记住这一点,您应该创建自己的语法,Antlr将为您生成一个lexer/解析器。您还将理所当然地在运行时对查询进行语法检查。如果查询的格式不正确,Antlr将无法解析查询。显然,某些语法规则将失败。这是另一个不按“原样”使用SQL的原因

  • 到目前为止,您已经创建了自己的侦听器/访问者。在我的例子中,我选择使用内部状态和所有内容创建查询的对象表示。 所以这个问题

  • 已转换为以下类型的对象:

    
    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
    
    }
    
    然后可以在查询中进行一些优化(如根据需要嵌入where子句,或者,例如,如果您使用的是多租户环境,并且针对不同租户有不同的集合,则可以操纵“for”部分)

    毕竟,您可以使用设计模式“解释器”,递归地解析查询对象,并将它们“翻译”为有效的mongo查询。
    我记得,考虑到表示查询的对象的正确结构,这一步花了我大约1天的时间才完成(我想这是7年前Mongo2的情况,但仍然如此),所以这应该没有那么复杂。我之所以提出这个问题,是因为它似乎是您在这个问题上最关心的问题。

    在我以前的一份工作中,我做了类似的事情:得到了一个查询(不是sql,但非常类似),并使用antlr将其转换为mongo查询

    我没有代码可供分享,但我可以分享我的想法:

  • Mongo不符合SQL,所以不能只接受SQL语法。连接和所有的关系代数呢?在mongo中使用聚合框架非常棘手的聚合怎么办?相反,如何生成在mongo中转换为“exists”子句的SQL。有很多类似的东西,有些很小,有些很大,但归根结底,你必须谈论的是某种sql子集,一些DSL被允许用作查询语言,看起来“像”sql,因为人们已经习惯了sql

  • 记住这一点,您应该创建自己的语法,Antlr将为您生成一个lexer/解析器。您还将理所当然地在运行时对查询进行语法检查。如果查询的格式不正确,Antlr将无法解析查询。显然,某些语法规则将失败。这是另一个不按“原样”使用SQL的原因

  • 到目前为止,您已经创建了自己的侦听器/访问者。在我的例子中,我选择使用内部状态和所有内容创建查询的对象表示。 所以这个问题

  • 已转换为以下类型的对象:

    
    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
    
    }
    
    然后可以在查询中进行一些优化(如根据需要嵌入where子句,或者,例如,如果您使用的是多租户环境,并且针对不同租户有不同的集合,则可以操纵“for”部分)

    毕竟,您可以使用设计模式“解释器”,递归地解析查询对象,并将它们“翻译”为有效的mongo查询。
    我记得,考虑到表示查询的对象的正确结构,这一步花了我大约1天的时间才完成(我想这是7年前Mongo2的情况,但仍然如此),所以这应该没有那么复杂。我之所以提出这个问题,是因为这似乎是你在这个问题上最关心的。

    谢谢马克。这似乎是一个非常简单的解决方案。我已经做完了,直到你提到的第二点。我从SQL语句中获取Parsetree对象。我只是想知道是否有任何parsetree遍历代码可以转换为mongo BSonies,但您是否使用了SQL的子集或整个SQL语法?整个SQL语法在本例中,请仔细阅读“1”项,其中我解释了为什么这是一个坏主意,至少对我的用例来说是…@Sahil,我想,这是一个很好的完整的答案,因为你可以回答你的问题,所以你至少可以投上一票。谢谢马克。这似乎是一个非常简单的解决方案。我已经做完了,直到你提到的第二点。我从SQL语句中获取Parsetree对象。我只是想知道是否有任何parsetree遍历代码可以转换为mongo BSonies,但您是否使用了SQL的子集或整个SQL语法?整个SQL语法在本例中,请仔细阅读“1”项,其中我解释了为什么这是一个坏主意,至少对我的用例来说是…@Sahil,我想,这是一个很好的完整的答案,因为你可能会得到你的问题,所以你至少可以投票。
    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));