我能够获得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)
答案 0 :(得分:0)
@1r3k 发布的上述答案应该有效,对我来说,出于不同的原因,它在 Apache Calcite 方面进行了小幅调整。
虽然它是一个不同的故事并且与这个问题没有直接关系,但让我详细说明可能对有类似问题的人有所帮助。
我的用例是在 Azure 上的 Cosmos DB 上运行标准 SQL,它提供用于连接的 MongoDB 驱动程序。
最新版本的 Apache Calcite 的问题在于它使用的是较旧的 MongoDB Java 驱动程序,并且已经有一段时间没有更新了。还有一个主要缺陷是它不接受任何可以在内部创建 MongoClient 时由 Apache Calcite 传递和使用的选项,请参阅下面来自 Apache Calcite 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。
答案 1 :(得分:-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的连接所需的所有数据。