Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb: db.printShardingStatus() / sh.status() call in Java (and JavaScript)

I need to get a list of chunks after sharding inside my Java code. My code is simple and looks like this:

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

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

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

A call of eval() returns an error:

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)

And, really, if we look into the code of db.js, in line 891 there is a call to a method printShardingStatus() that is not defined inside a file. Inside of sh.status() method in utils_sh.js file, there is even a comment:

// TODO: move the actual commadn here

Important to mention, when I run these commands in mongo command line, everything works properly!

My questions are:

  • Is there any other possibility of getting a full sharding status within Java code? (eg. with DB.command() method)
  • If not, any other suggestions how to avoid my problem?
like image 807
Paweł Skorupiński Avatar asked Mar 27 '26 14:03

Paweł Skorupiński


2 Answers

Many of the shell's helper functions are not available for server-side code execution. In the case of printShardingStatus(), it makes sense because there isn't a console to use for printing output and you'd rather have a string returned. Thankfully, you should be able to pull up the source of the shell function and reimplement it in your application (e.g. concatenating a returned string instead of printing directly).

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

So, let's look at the printShardingStatus() function...

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

    // ...
}

Before turning all of the output statements into string concatenation, you'd want to make sure the other DB methods are all available to you. Performance-wise, I think the best option is to port the innards of this function to Java and avoid server-side JS evaluation altogether. If you dive deeper into the printShardingStatus() function, you'll see it's just issuing find() on the config database along with some group() queries.

If you do want to stick with evaluating JS and would rather not keep this code within your Java application, you can also look into storing JS functions server-side.

like image 77
jmikola Avatar answered Mar 29 '26 04:03

jmikola


Have you deployed a shard cluster properly? If so, you could connect to a mongo database that has sharding enabled.

Try calling the method db.printShardingStatus() with a that database within the mongo shell and see what happens.

Apparently the Javascript function 'printShardingStatus' is only available for the mongo shell and not for execution with server commands, to see the code start mongo.exe and type only 'printShardingStatus' and press enter.

In this case writing an extension method would be the best for solving this...

like image 35
Kevin Avatar answered Mar 29 '26 04:03

Kevin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!