Node.js 如何检查Mongodb本机nodejs驱动程序中是否存在集合?
我需要检查某个数据库上是否存在集合,如果不存在,则创建集合。我知道Node.js 如何检查Mongodb本机nodejs驱动程序中是否存在集合?,node.js,mongodb,node-mongodb-native,Node.js,Mongodb,Node Mongodb Native,我需要检查某个数据库上是否存在集合,如果不存在,则创建集合。我知道 db.createCollection(collName, {strict:true}, function(error, collection)) 在创建集合之前检查集合collName是否存在,并设置error对象。但我需要一个独立的函数来检查这一点。在MongoDB 3.0及更高版本中,您必须运行命令来列出数据库中的所有集合: use test; db.runCommand( { listCollections: 1 }
db.createCollection(collName, {strict:true}, function(error, collection))
在创建集合之前检查集合
collName
是否存在,并设置error
对象。但我需要一个独立的函数来检查这一点。在MongoDB 3.0及更高版本中,您必须运行命令来列出数据库中的所有集合:
use test;
db.runCommand( { listCollections: 1 } );
尽管在使用默认存储引擎(MMAPv1)时,查询system.namespace
仍能工作,但不能保证它适用于其他引擎,如WiredTiger
在MongoDB 3.0之前,您需要执行以下操作:
use test;
db.runCommand( { listCollections: 1 } );
您可以查询系统名称空间集合:
use test;
db.system.namespace.find( { name: 'test.' + collName } );
db.collectionNames(collName, function(err, names) {
console.log('Exists: ', names.length > 0);
});
例如:
db.system.namespaces.find( { name: 'test.testCollection' } );
返回:
{ "name" : "test.testCollection", "options" : { "flags" : 1 } }
当然,也没什么
另请参见:本机驱动程序的Db
对象的方法接受可选的集合名称筛选器作为第一个参数,以允许您检查集合是否存在:
use test;
db.system.namespace.find( { name: 'test.' + collName } );
db.collectionNames(collName, function(err, names) {
console.log('Exists: ', names.length > 0);
});
在MongoDB本机驱动程序的2.x版本中,collectionNames
已被替换为接受筛选器并返回游标的,因此您可以按以下方式执行此操作:
db.listCollections({name: collName})
.next(function(err, collinfo) {
if (collinfo) {
// The collection exists
}
});
这个问题涉及本机驱动程序,但我在这里搜索如何在pymongo
中实现这一点。通常,pymongo
的api与JS api相同,但在本例中,collection\u names
没有集合名称的参数(如johnyhk
),而是第一个参数是布尔值(是否包括系统集合)。由于字符串的计算结果为True
,因此可能会造成混淆。因此,我希望这能帮助未来的读者:
import pymongo
cl = pymongo.MongoClient()
db = cl['my-db']
if 'my-col' in db.collection_names(False):
...
Node.js本机驱动程序中现在有一个方法。它返回当前数据库中所有集合的信息。您可以使用它检查给定集合是否存在:
collectionExists = function(name, cb) {
mongoDb.listCollections().toArray(function(err, collections) {
if (err) return cb(err);
cb(null, collections.some(function(coll) {
return coll.name == name;
}));
});
}
由于MongoDB 3.0,您只需运行:
db.getCollectionNames()
它返回一个数组,其中包含当前数据库中所有集合的名称:
[ "employees", "products", "mylogs"]
选中,或者您也可以使用db.getCollectionFos()。如果您需要有关使用driver和7.6+的每个集合的更多信息,请使用以下命令:
const collections = await db.collections();
if (!collections.map(c => c.s.name).includes(collName)) {
await db.createCollection(collName);
}
编辑
正如@MattCochrane提到的,collection.s.name
不再可用;正如@johnyhk和@weekens指出的,正确的方法是使用以下方法:
listCollection()
采用可选过滤器。如果使用mongodb 3.1.10。
这是检查集合是否存在的方法
MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
if (err) throw err;
var dbo = client.db("dbname");
dbo.listCollections().toArray(function(err, items){
if (err) throw err;
console.log(items);
if (items.length == 0)
console.log("No collections in database")
});
});
适用于3.6.*版本的更新答案
/**
*检查mongo数据库中是否存在集合。
*
*@param db是一个mongo db对象。如。
*client=wait MongoClient.connect(uri);
*db=client.db();
*@param collectionName要搜索的集合的名称
*@returns{Promise}
*/
异步函数doesCollectionExistInDb(db,collectionName){
const collections=await db.collections();
返回集合(
(collection)=>collection.collectionName===collectionName
);
}
...
如果(等待doesCollectionExistInDb(db,‘产品’)){
//执行某些操作,例如创建新集合
}
collection.collectionName
是文档化的集合api的一部分,可以在这里找到:对于使用mongodb库(V3.6.3)的nodejs,这是我让它工作的唯一方法:
const collectionName = 'products'
const exists = (await (await db.listCollections().toArray()).findIndex((item) => item.name === collectionName) !== -1)
console.log(exists)
希望这能帮助别人
/* set database */
let db = client.db( 'crud' )
/* set collection */
let collection = db.collection( 'categories' )
/* set query */
collection.find( {} ).toArray( ( err, result ) => {
if ( result.length > 0 )
{
console.log("Exist");
}
else
{
console.log("Not Exist");
// create collection
}
}事实上,这对我很有用
await db.createCollection(name, function (err, res) {
if (err) {
//console.log(err);
if (err.codeName =="NamespaceExists") {
console.log("Already Exists Collection : " + name + "");
return;
}
}
console.log("Collection created! : "+name+"");
});
需要更多信息:您使用的是哪一个连接器库,您检查过它的手册/api文档吗?@Mike'Pomax'Kamermans我使用的是驱动程序库,但在它的api文档中找不到这样的功能。in:db.collection('system.namespace').find().toArray(函数(err,items){}
晚会迟到了,但是我认为我下面的答案()有一个更直接、更清晰的方法来获取信息。答案中的所有内容都不能在native node.js库中找到。唯一有效的是Nasser提供的内容。到今天为止,这个答案不再有效,`db.listCollections({name:collName}).next(函数(err,collinfo){if(collinfo){//集合存在}});`是如何在nodejs中获取此db对象的有效答案吗?方法getCollectionNames()
在node.js native lib中不可用。嘿,但我使用的是mongodb lib,它是管理mongo数据库@DanFromGermany的方法,旧API中有,但没有getCollectionNames()
没有问题。您使用的是哪个版本的MongoDB,这个getCollectionNames()存在于MongoDB 3.0Dude中,mongo的最新节点驱动程序是。3.0甚至不存在。这应该是可接受的答案,因为它是实际处理node.js的唯一答案(如OP要求的)。还有一个linerdb.listCollections({name:colName})。hasNext()
@NikolaLukic在cb
函数中,第一个参数是错误(null
,如果没有错误),第二个参数是布尔值,如果存在集合,则为true
;如果不存在集合,则为false
collectionExists
函数也可以通过承诺而不是回调来实现。我已经有了与listCollections()相同的信息。toArray。我需要编写简单的函数,比如:isExist(name),并像if(isExist('mycollection')==true){doSomething();}一样使用它。也许我需要异步方法…@NikolaLukic,是的,你可能会得到if(wait isExist('mycollection'))
或if(yield isExist('mycollection'))
。没有其他方法可以使异步方法看起来像同步方法。我猜,==true
是多余的。刚刚测试了这个节点v8.11.4-mongodb-3.1.10:它工作得很好!您可以使用some()
而不是map
和includes
将其缩短一点。这在mongodb 3.6.0中不再有效,name
属性在collection.s
上不可用。给我一个教训。。我应该比t更清楚