我想确保mongodb中还没有一些数据库,但是只要我访问db对象,就会创建一个空数据库。
使用node-mongodb-native驱动程序:
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:27017/nonexistingdb", function(err, db) {
db.eval('db.getMongo().getDBNames();',function(err, dbnames) {
console.log(dbnames);
db.close();
});
});
+
$ mongo --eval "db.getMongo().getDBNames();"
MongoDB shell version: 2.4.9
connecting to: test
local
使用mongo shell时不会那样:
$ cat > byshell.js
server = new Mongo();
db = server.getDB("nonexistentdb");
dbnames = server.getDBNames();
print(dbnames);
+
$ mongo --nodb byshell.js
MongoDB shell version: 2.4.9
local
+
$ mongo --eval "db.getMongo().getDBNames();"
MongoDB shell version: 2.4.9
connecting to: test
local
我该怎么做才能避免这种情况?
答案 0 :(得分:0)
由于使用数据库名称调用MongoClient.connect
类似于在mongo CLI中键入use dbname
,因此连接操作将创建数据库(如果它不存在),我想是唯一的确保连接后不存在特定数据库的方法是在连接之后调用db.dropDatabase
,但实际上会破坏连接调用的目的。
在深入研究代码之后,似乎MongoClient.connect
做的最后一件事就是打开在其连接URI中命名的数据库,这显然有创建数据库的副作用,如果它没有存在。 (参见node_modules/mongodb/lib/mongodb/mongo_client.js
)
因此有趣的是,通过使用MongoClient.connect
,您别无选择,只能接受此行为,因为要求您包含dbname
作为您必须提供的Mongo连接字符串URI,这与此类事件的official definition相反。
因此,如果您不希望自动在连接到Mongo时创建不存在的数据库,那么您不应该依赖官方mongodb.js
驱动程序及其MongoClient API。
您可以尝试使用支持更多Mongo Shell比喻的API来包装mongodb.js
驱动程序的mongojs,如下所示:
var util=require('util'),
mongojs=require('mongojs'),
connectionUriWithoutDb='localhost/', // *see note below.
db=mongojs(connectionUriWithoutDb);
db.runCommand({ping:1},function(err,res){
if(err) throw err;
console.log('result: %s', util.inspect(res));
db.close();
});
打印到控制台:
result: { ok: 1 }
并且不会创建数据库。
mongodb.js
驱动程序您正在指定主机名而不是数据库名恰好包含句号。 没有斜杠,mongodb.js
会抛出异常(validateDatabaseName
的第216行每node_modules/mongojs/node_modules/mongodb/lib/mongodb/db.js
},因为数据库名称不能包含空格,句点,美元符号,以及转发或向后斜线。
奇怪的是,这个测试是在这五个字符的列表上的Array.prototype.indexOf变种,而不是使用一个RegExp,它会禁止使用除允许之外的任何字符。
我的下一个数据库名称肯定必须包含几个换行符,至少一个铃声和一个或两个选项卡。 ;)