如何检查MongoDB本机nodejs驱动程序中是不是存在集合?
Posted
技术标签:
【中文标题】如何检查MongoDB本机nodejs驱动程序中是不是存在集合?【英文标题】:How to check if a collection exists in Mongodb native nodejs driver?如何检查MongoDB本机nodejs驱动程序中是否存在集合? 【发布时间】:2014-01-28 05:25:16 【问题描述】:我需要检查某个数据库上是否存在集合,如果不存在则创建它。我知道
db.createCollection(collName, strict:true, function(error, collection))
在创建集合之前检查集合collName
的存在并设置error
对象。但我需要一个独立的函数来检查。
【问题讨论】:
需要更多信息:您使用的是哪个连接器库,您是否查看过它的手册/api 文档? @Mike'Pomax'Kamermans 我正在使用mongo-native 驱动程序库,但我在它的 API 文档中找不到这样的功能。 【参考方案1】:在 MongoDB 3.0 及更高版本中,您必须运行命令来列出数据库中的所有集合:
use test;
db.runCommand( listCollections: 1 );
虽然在使用默认存储引擎 (MMAPv1) 时查询system.namespaces
仍然有效,但不保证对其他引擎也有效,例如 WiredTiger。
在 MongoDB 3.0 之前,您需要执行以下操作:
可以查询system.namespaces
集合:
use test;
db.system.namespace.find( name: 'test.' + collName );
喜欢:
db.system.namespaces.find( name: 'test.testCollection' );
返回:
"name" : "test.testCollection", "options" : "flags" : 1
当然,什么也没有。
另请参阅:https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst
【讨论】:
在mongo-native:db.collection('system.namespaces').find().toArray(function(err, items) )
迟到了,但我认为我在下面的回答 (***.com/a/40141321/446717) 有一种更直接、更干净的方法来获取该信息
本机 node.js 库中没有答案中的任何内容。 Nasser 提供的唯一有效的东西。
从今天开始,这个答案不再有效,` db.listCollections(name: collName) .next(function(err, collinfo) if (collinfo) // 集合存在 ); ` 是来自this answer 的有效答案
如何在nodejs中获取这个db对象?【参考方案2】:
本机驱动程序的Db
对象的collectionNames
方法接受一个可选的集合名称过滤器作为第一个参数,让您检查集合是否存在:
db.collectionNames(collName, function(err, names)
console.log('Exists: ', names.length > 0);
);
在 2.x 版本的 MongoDB 原生驱动程序中,collectionNames
已被替换为 listCollections
,它接受过滤器并返回游标,因此您可以这样做:
db.listCollections(name: collName)
.next(function(err, collinfo)
if (collinfo)
// The collection exists
);
【讨论】:
这应该是公认的答案,因为它是唯一真正处理 node.js 的答案(就像 OP 要求的那样)。 还有一个班轮db.listCollections( name: colName ).hasNext()
【参考方案3】:
这个问题是指本机驱动程序,但我在这里搜索如何在pymongo
中执行此操作。通常pymongo
的 api 与 JS api 相同,但在这种情况下,collection_names
没有集合名称的参数(如JohnnyHK
的answer),而是第一个参数是一个布尔值(是否包括系统集合)。由于字符串的计算结果为True
,这可能会造成混淆。所以我希望这对未来的读者有所帮助:
import pymongo
cl = pymongo.MongoClient()
db = cl['my-db']
if 'my-col' in db.collection_names(False):
...
【讨论】:
【参考方案4】:Node.js 原生驱动程序中现在有一个listCollections 方法。它返回当前数据库中所有集合的信息。您可以使用它来检查给定的集合是否存在:
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;
));
);
【讨论】:
@NikolaLukic 在cb
函数中,第一个参数是错误(null
如果没有错误),第二个参数是布尔值,如果集合存在则为true
,如果不存在则为false
。 collectionExists
函数也可以用 Promise 代替回调来实现。
我已经有了与 listCollections().toArray 相同的信息。我需要编写简单的函数,例如: isExist (name) ,并像 if (isExist('mycollection') == true) doSomething(); 一样使用它 也许我需要异步方法...
@NikolaLukic,是的,您最终可能会得到if (await isExist('mycollection'))
或if (yield isExist('mycollection'))
。没有其他方法可以使异步方法看起来像同步方法。我猜,== true
是多余的。【参考方案5】:
从 MongoDB 3.0 开始,您可以简单地运行:
db.getCollectionNames()
返回一个包含当前数据库上所有集合名称的数组:
[ "employees", "products", "mylogs"]
检查Mongo DB Documentation,或者如果您需要有关每个集合的更多信息,也可以使用 db.getCollectionInfos()
【讨论】:
方法getCollectionNames()
在node.js原生库中不可用。
嘿,但我是从 mongodb lib 中使用它的,它是管理 mongo 数据库的一个 @DanFromGermany
旧 API 中有 Db.collectionNames()
可用,但根本没有 getCollectionNames()
。
你使用的是哪个版本的MongoDB,这个getCollectionNames()存在于MongoDB 3.0中
老兄,mongo的最新节点驱动是2.2
(link)。 3.0 甚至都不存在。【参考方案6】:
使用mongo-native驱动和Node.js 7.6+,我使用以下:
const collections = await db.collections();
if (!collections.map(c => c.s.name).includes(collName))
await db.createCollection(collName);
编辑
正如@MattCochrane 提到的,collection.s.name
不再可用;正如@JohnnyHK 和@weekens 指出的那样,正确的方法是使用listCollections()
方法:
const client = new MongoClient(connectionString, useUnifiedTopology: true );
await client.connect();
const collections = await client.db().listCollections().toArray();
const collectionNames = collections.map(c => c.name);
listCollection()
采用可选过滤器。
【讨论】:
刚刚测试了这个 Node v8.11.4 - mongodb - 3.1.10:效果很好! 你可以用some()
代替map
和includes
developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 来缩短这个时间
这在 mongodb 3.6.0 中不再有效,name
属性在 collection.s
上不可用。对我来说是一个教训。我应该知道不要使用显然不打算成为公共接口的东西。【参考方案7】:
如果你使用 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")
);
);
【讨论】:
【参考方案8】:适用于 3.6.* 版本的更新答案。
/**
* Checks if a collection exists in a mongo database.
*
* @param db a mongo db object. eg.
* client = await MongoClient.connect(uri);
* db = client.db();
* @param collectionName the name of the collection to search for
* @returns Promise<boolean>
*/
async function doesCollectionExistInDb(db, collectionName)
const collections = await db.collections();
return collections.some(
(collection) => collection.collectionName === collectionName
);
...
if (await doesCollectionExistInDb(db, 'products'))
// Do something, such as create a new collection
collection.collectionName
是记录在案的集合 api 的一部分,可在此处找到:http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#collectionName
【讨论】:
这在 2021 年对我有用,非常干净的解决方案!【参考方案9】:对于带有 mongodb 库 (v 3.6.3) 的 nodejs,这是我让它工作的唯一方法:
const collectionName = 'products'
const exists = (await (await db.listCollections().toArray()).findIndex((item) => item.name === collectionName) !== -1)
console.log(exists)
希望对他人有所帮助
【讨论】:
【参考方案10】:/* 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
【讨论】:
【参考方案11】:实际上,这对我有用
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+"");
);
【讨论】:
【参考方案12】:一个异步 TypeScript 函数:
/**
* Predicate function that checks if a collection exists in a given MongoDB database
*
* @param Db db Mongo database instance
* @param string collectionName Name of collection
*
* @returns boolean true if collection exists, false otherwise
*/
export const doesCollectionExist = async (db: Db, collectionName: string): Promise<boolean> =>
const cursor = db.listCollections( name: collectionName )
const result = await cursor.hasNext()
await cursor.close()
return result
【讨论】:
以上是关于如何检查MongoDB本机nodejs驱动程序中是不是存在集合?的主要内容,如果未能解决你的问题,请参考以下文章
NodeJS 本机驱动程序上的示例 MongoDB 错误是啥样的?
为桌面、移动本机应用程序和 oAuth 功能设计 nodejs expressjs mongodb Webserver 流