访问db而不留下空数据库。[node-mongodb-native]

时间:2014-01-28 18:38:41

标签: node.js mongodb node-mongodb-native

我想确保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

我该怎么做才能避免这种情况?

1 个答案:

答案 0 :(得分:0)

由于使用数据库名称调用MongoClient.connect类似于在mongo CLI中键入use dbname,因此连接操作将创建数据库(如果它不存在),我想是唯一的确保连接后不存在特定数据库的方法是在连接之后调用db.dropDatabase,但实际上会破坏连接调用的目的。

更新

在深入研究代码之后,似乎MongoClient.connect做的最后一件事就是打开在其连接URI中命名的数据库,这显然有创建数据库的副作用,如果它没有存在。 (参见node_modules/mongodb/lib/mongodb/mongo_client.js

中的第371行

因此有趣的是,通过使用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 }

并且不会创建数据库。

  • 请注意,如果选择以这种方式连接,则必须记住使用斜杠结束连接字符串URI,以通知基础mongodb.js驱动程序您正在指定主机名而不是数据库名恰好包含句号

没有斜杠,mongodb.js会抛出异常(validateDatabaseName的第216行每node_modules/mongojs/node_modules/mongodb/lib/mongodb/db.js},因为数据库名称不能包含空格,句点,美元符号,以及转发或向后斜线。

奇怪的是,这个测试是在这五个字符的列表上的Array.prototype.indexOf变种,而不是使用一个RegExp,它会禁止使用除允许之外的任何字符。

我的下一个数据库名称肯定必须包含几个换行符,至少一个铃声和一个或两个选项卡。 ;)