MongoDB通过JavaDriver执行shell命令,例如创建sharding collection

Mongodb的java driver本身的接口

void createCollection(String collectionName, CreateCollectionOptions createCollectionOptions)

是不支持创建一个sharding collection的,通过此方式创建的collection不支持分片,即此表存放在一个节点上。传统的方式是通过mongodb的shell命令(见之前的文章),如

sh.shardCollection("dbname.tablename", {"_id": "hashed"}) to create a shard table hashed by _id

但是这种方式也有一定的制约,不能通过程序动态的添加表,如果我默认的表不足以支撑业务,就必须通过shell方式创建一个sharding表,之后再插入数据才能满足要求。

通过javadoc的查询,MongoDatabase存在如下接口:

Document runCommand(Bson command)

也就是说,通过此接口可以执行runCommand命令。而runCommand命令是什么呢?通过官方reference(https://docs.mongodb.com/manual/reference/command/shardCollection/)的查询,我们看到如下说明:

Shards a collection to distribute its documents across shards. You must run enableSharding on a database before running the shardCollection command. The shardCollection command must be run against the admin database.

To run shardCollection, use the db.runCommand( { <command> } ) method.

shardCollection has the following form:

{
   shardCollection: "<database>.<collection>",
   key: <shardkey>,
   unique: <boolean>,
   numInitialChunks: <integer>,
   collation: { locale: "simple" }
}

也就是说,我们可以通过shell命令,执行db.runCommand({shardCollection:"db.collection", key: {"_id": "hashed"}})来执行此命令。

对于java driver而言,我们只要把命令中的json当参数调用runCommand应当就可以实现创建sharding表了。

接下来看java driver的接口,传递参数是一个Bson,之前我们进行查询以及过滤时生成过Bson,不过那些model显然不全,只是为了查询方便Mongodb帮我们建好的,里面并不包含shardCollection。于是去javadoc找到对应的Bson:

http://mongodb.github.io/mongo-java-driver/3.4/javadoc/

里面有

org.bson.conversions

Interface Bson

找到此Interface后看下面有哪些类implement了此接口。

Class BasicDBObject

接下来去此BasicDBObject页面看看怎么用就可以了,具体实现方式为:

lazy val mongoURI = new MongoClientURI(new MongoUserUtils().origin2URI)
lazy val mongo = new MongoClient(mongoURI)
//这里必须是admin,只有admin库才有创建shardingcollection的权限。
lazy val db = mongo.getDatabase("admin")
val bs = new BasicDBObject()
bs.append("shardCollection", "test.testsharding2")
bs.append("key", mapAsJavaMap(Map(("_id", "hashed"))))
println(bs.toJson())
db.runCommand(bs)