Mongodb:用Java(和JavaScript)调用db.printShardingStatus()/ sh.status()

Paw*_*ski 2 java sharding status chunks mongodb

在我的Java代码内部分片后,我需要获取一个块列表.我的代码很简单,看起来像这样:

Mongo m = new Mongo( "localhost" , 27017 );

DB db = m.getDB( "admin" );

Object cr = db.eval("db.printShardingStatus()", 1);
Run Code Online (Sandbox Code Playgroud)

调用eval()会返回错误:

Exception in thread "main" com.mongodb.CommandResult$CommandFailure: command failed [$eval]: { "serverUsed" : "localhost/127.0.0.1:27017" , "errno" : -3.0 , "errmsg" : "invoke failed: JS Error: ReferenceError: printShardingStatus is not defined src/mongo/shell/db.js:891" , "ok" : 0.0}
    at com.mongodb.CommandResult.getException(CommandResult.java:88)
    at com.mongodb.CommandResult.throwOnError(CommandResult.java:134)
    at com.mongodb.DB.eval(DB.java:340)
    at org.sm.mongodb.MongoTest.main(MongoTest.java:35)
Run Code Online (Sandbox Code Playgroud)

而且,实际上,如果我们查看db.js的代码,在第891行中会调用一个未在文件中定义的方法printShardingStatus().在utils_sh.js文件中的sh.status()方法内部,甚至还有一条注释:

// TODO:在这里移动实际的commadn

重要的是,当我在mongo命令行中运行这些命令时,一切正常!

我的问题是:

  • 是否还有其他可能在Java代码中获得完整的分片状态?(例如,使用DB.command()方法)
  • 如果没有,任何其他建议如何避免我的问题?

jmi*_*ola 7

许多shell的辅助函数不能用于服务器端代码执行.在这种情况下printShardingStatus(),它是有道理的,因为没有用于打印输出的控制台,你宁愿返回一个字符串.值得庆幸的是,您应该能够提取shell函数的源代码并在应用程序中重新实现它(例如,连接返回的字符串而不是直接打印).

$ mongo
MongoDB shell version: 2.2.0
connecting to: test
> db.printShardingStatus
function (verbose) {
    printShardingStatus(this.getSiblingDB("config"), verbose);
}
Run Code Online (Sandbox Code Playgroud)

那么,让我们来看看这个printShardingStatus()功能......

> printShardingStatus
function (configDB, verbose) {
    if (configDB === undefined) {
        configDB = db.getSisterDB("config");
    }
    var version = configDB.getCollection("version").findOne();

    // ...
}
Run Code Online (Sandbox Code Playgroud)

在将所有输出语句转换为字符串连接之前,您需要确保其他数据库方法都可供您使用.在性能方面,我认为最好的选择是将此函数的内部移植到Java并完全避免服务器端的JS评估.如果您深入了解该printShardingStatus()功能,您将看到它只是find()在配置数据库上发布以及一些group()查询.

如果您确实希望坚持评估JS并且不希望将此代码保留在Java应用程序中,那么您还可以考虑在服务器端存储JS函数.