2

在我的 Java 代码中分片后,我需要获取一个块列表。我的代码很简单,如下所示:

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

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

Object cr = db.eval("db.printShardingStatus()", 1);

调用 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)

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

// TODO: 把实际的命令移到这里

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

我的问题是:

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

3 回答 3

7

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

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

那么,让我们看一下printShardingStatus()函数...

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

    // ...
}

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

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

于 2012-10-02T15:44:24.983 回答
1

您是否正确部署了分片集群?如果是这样,您可以连接到启用了分片的 mongo 数据库。

尝试在 mongo shell 中使用该数据库调用 db.printShardingStatus() 方法,看看会发生什么。

显然,Javascript 函数“printShardingStatus”仅适用于 mongo shell,不能用于服务器命令执行,要查看代码启动 mongo.exe 并仅键入“printShardingStatus”并按 Enter。

在这种情况下,编写扩展方法将是解决此问题的最佳方法......

于 2012-10-02T13:56:21.790 回答
1

将MongoDB查询的输出打印到文件的Javascript方式

1]创建一个javascript文件

测试.js

cursor = db.printShardingStatus();
while(cursor.hasNext()){
    printjson(cursor.next());
}

2]运行

mongo admin --quiet test.js > output.txt
于 2012-10-23T09:24:39.827 回答