【问题标题】:Apache Calcite | Querying data from MongoDB by using Relational algebra阿帕奇方解石 |使用关系代数从 MongoDB 查询数据
【发布时间】:2021-06-18 02:12:33
【问题描述】:

我能够得到一个 MongoDB 连接并且能够得到一个节点

(LogicalTableScan(table=[[enlivenDev, collection1]]))

但是当我执行节点时,我得到空指针异常。

完整代码:

private void executeMongoDB(){
        final FrameworkConfig config = mongoConfig().build();
        final RelBuilder builder = RelBuilder.create(config);
        final RelNode node =  builder.scan("collection1").build();
        System.out.println(RelOptUtil.toString(node));  
        PreparedStatement ps = RelRunners.run(node);
        ResultSet resultSet = ps.executeQuery();
}
    public static Frameworks.ConfigBuilder mongoConfig() {
            final SchemaPlus rootSchema = Frameworks.createRootSchema(true);
            org.apache.calcite.tools.Frameworks.ConfigBuilder configBuilder =Frameworks.newConfigBuilder()
                    .parserConfig(SqlParser.Config.DEFAULT)
                    .defaultSchema(
                        MongoDBConnection.addMongoSchema(rootSchema, CalciteAssert.SchemaSpec.MONGO_DB))
                    .traitDefs((List<RelTraitDef>) null)
                    .programs(Programs.heuristicJoinOrder(Programs.RULE_SET, true, 2));
            return configBuilder;
        }
public static SchemaPlus addMongoSchema(SchemaPlus rootSchema, SchemaSpec schema) {
        switch (schema) {
        case MONGO_DB:
            return rootSchema.add("enlivenDev",
                    MongoSchemaFactory.create(rootSchema, "192.168.1.01", "enlivenDev", 27017, "mgp", "mg1"));
        default:
            throw new AssertionError("unknown schema " + schema);
        }
    }

从上面的代码中得到以下异常,有模式获取空值,同时执行 Mongo DB 集合的 relnode

SEVERE: exception while executing query: null
java.sql.SQLException: exception while executing query: null
    at org.apache.calcite.avatica.Helper.createException(Helper.java:56)
    at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
    at org.apache.calcite.avatica.AvaticaConnection.executeQueryInternal(AvaticaConnection.java:540)
    at org.apache.calcite.avatica.AvaticaPreparedStatement.executeQuery(AvaticaPreparedStatement.java:133)
    at org.ramyam.eis.core.ApachecalcitePOC.processMongoDB(ApachecalcitePOC.java:106)
    at org.ramyam.eis.core.ApachecalcitePOC.main(ApachecalcitePOC.java:42)
Caused by: java.lang.NullPointerException
    at org.apache.calcite.schema.Schemas.queryable(Schemas.java:232)
    at Baz.bind(Unknown Source)
    at org.apache.calcite.jdbc.CalcitePrepare$CalciteSignature.enumerable(CalcitePrepare.java:335)
    at org.apache.calcite.jdbc.CalciteConnectionImpl.enumerable(CalciteConnectionImpl.java:294)
    at org.apache.calcite.jdbc.CalciteMetaImpl._createIterable(CalciteMetaImpl.java:559)
    at org.apache.calcite.jdbc.CalciteMetaImpl.createIterable(CalciteMetaImpl.java:550)
    at org.apache.calcite.avatica.AvaticaResultSet.execute(AvaticaResultSet.java:204)
    at org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:67)
    at org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:44)
    at org.apache.calcite.avatica.AvaticaConnection.executeQueryInternal(AvaticaConnection.java:536)

【问题讨论】:

  • 你能显示完整的异常吗?
  • 添加了完整的例外
  • 任何人都可以帮我解决这个问题。谢谢提前

标签: apache-calcite


【解决方案1】:

这应该会有所帮助:

public void useCalcite(String modelPath) {
    Connection connection = DriverManager.getConnection("jdbc:calcite:model=" + modelPath);
    CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
    String query = "select count(*) from zips";
    Statement statement = calciteConnection.createStatement();
    ResultSet result = statement.executeQuery(query);
    ...
}

您需要一个收藏模型。像这样:model-example 模型文件包含建立与 mongodb 的连接所需的所有数据。

【讨论】:

    【解决方案2】:

    @1r3k 发布的上述答案应该可以工作,对我来说,由于不同的原因,它在 Apache Calcite 方面进行了小幅调整。

    虽然它是一个不同的故事并且与此问题没有直接关系,但让我详细说明可能对遇到类似问题的人有所帮助。

    我的用例是在 Azure 上的 Cosmos DB 上运行标准 SQL,它提供 MongoDB 驱动程序进行连接。

    最新版本的 Apache Calcite 的问题在于它使用的是较旧的 MongoDB Java 驱动程序,并且已经有一段时间没有更新了。还有一个主要缺陷是它不接受 Apache Calcite 在内部创建 MongoClient 时可以传递和使用的任何选项,请参阅下面来自 Apache Calcite 的代码 sn-p https://github.com/apache/calcite/blob/master/mongodb/src/main/java/org/apache/calcite/adapter/mongodb/MongoSchema.java

    MongoSchema(String host, String database,
      MongoCredential credential, MongoClientOptions options) {
    super();
    try {
      final MongoClient mongo = credential == null
          ? new MongoClient(new ServerAddress(host), options)
          : new MongoClient(new ServerAddress(host), credential, options);
      this.mongoDb = mongo.getDatabase(database);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }}
    

    这需要更新,并且已经提出了相同的 PR,但不确定何时合并,详细信息在这里

    https://github.com/apache/calcite/pull/2345

    使用上述更改和模型文件中的微小更改就可以正常连接。模型文件中的更改是仅使用连接 URL,而不是传递主机和其他详细信息。连接字符串将包含所有必需的连接选项,其中包括启用 SSL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      相关资源
      最近更新 更多