Доступ к базе данных, не оставляя пустой базы данных. [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:

$ 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

Что я могу сделать, чтобы избежать этого?


person Green Hell    schedule 28.01.2014    source источник


Ответы (1)


Поскольку вызов MongoClient.connect с именем базы данных аналогичен вводу use dbname в CLI mongo, так что акт подключения создаст базу данных, если она не существует, я представляю единственный способ убедиться, что конкретная база данных не существует после подключения будет вызывать db.dropDatabase после подключения к нему, но на самом деле не будет иметь смысла вызов подключения.

Обновлять

Покопавшись в коде, кажется, что одна из последних вещей, которую делает MongoClient.connect, — это открытие базы данных, названной в его URI подключения, что явно имеет побочный эффект создания базы данных, если она не существует. (См. строку 371 или около того в node_modules/mongodb/lib/mongodb/mongo_client.js)

Поэтому интересно отметить, что при использовании MongoClient.connect у вас нет другого выбора, кроме как согласиться с таким поведением, поскольку оно требует включения dbname как части URI строки подключения Mongo, который вы должны предоставить, что противоречит к официальному определению таких вещей.

Таким образом, если вы не хотите автоматически создавать несуществующие базы данных при подключении к Mongo, вам не следует полагаться на официальный драйвер mongodb.js и его MongoClient API.

Вы можете попробовать mongojs, который обертывает драйвер mongodb.js API, поддерживающим больше метафоры Mongo Shell, как в :

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 со списком из этих пяти символов, а не с использованием регулярного выражения, которое запрещало бы использование любых символов, кроме разрешенных.

Мое следующее имя базы данных обязательно должно содержать несколько новых строк, по крайней мере, один колокольчик и табуляцию или две. ;)

person Rob Raisch    schedule 28.01.2014
comment
Что ж, use dbname не оставит его, если вы не выполните вставку, обновление или другую операцию записи. Он создается, когда вы используете/подключаетесь к нему, но только для этого сеанса, если вы не записываете в него. Я понимаю, что это не часто встречается, но если бы они рассматривали это в оболочке, я бы ожидал, что это будет то же самое в API. - person Green Hell; 29.01.2014