Node.js - Mongoose - 检查集合是否存在

31

我需要使用mongoose插入一些数据,但集合的名称由用户在插入时提供,所以我必须先检查该集合是否存在。

我知道如何检查集合是否存在,即查询system.namespaces集合。 我可以看到有3种可能的方法来完成此操作。

  1. 找到一种使用mongoose查询system.namespaces的方法(也许定义与数据库中匹配的模式)。
  2. 从mongoose获取某些底层的node-mongodb-native对象,手动执行查询。 无论如何,这是我想要学习的内容。
  3. 使用单独的一个node-mongodb-native实例(或其他驱动程序)来执行查询。

3种方法最不优雅,我正在尝试避免它,因为我不想在mongoose已经创建了一个连接时再加载另一个驱动程序实例或创建新连接。

写完这篇文章后,我将尝试第1种方法。 我刚刚检查了system.namespaces,发现架构非常简单。

我仍然想听听一些意见。

谢谢!

5个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
43

选项2可能是最简单的。假设你有一个名为conn的Mongoose Connection对象,该对象已使用mongoose.createConnection打开,你可以通过conn.db访问原生mongo Db对象。从那里,你可以调用collectionNames,这应该会提供你所寻找的内容:

conn.db.collectionNames(function (err, names) {
    // names contains an array of objects that contain the collection names
});

你还可以将集合名称作为参数传递给collectionNames,以筛选出你所需要的结果。

Mongoose 4.x更新说明

在Mongoose 4.x中使用的MongoDB原生驱动程序的2.x版本中,collectionNames已被listCollections所取代,它接受一个过滤器并返回一个游标,因此你可以这样做:

mongoose.connection.db.listCollections({name: 'mycollectionname'})
    .next(function(err, collinfo) {
        if (collinfo) {
            // The collection exists
        }
    });

4
这对我有效(mongoose版本5.1.1):
const mongoose = require('mongoose');
const mongoURI = 'mongodb://localhost:27017/mydb'
// notice the mongoose.createConnection instead of mongoose.connect
const conn = mongoose.createConnection(mongoURI);
conn.on('open', function () {
    conn.db.listCollections().toArray(function (err, collectionNames) {
      if (err) {
        console.log(err);
        return;
      }
        console.log(collectionNames);
        conn.close();
    });
});

我喜欢你引用了常量(mongoosemongoURIconn),因为我觉得这在被接受的答案中是缺失的,因为你的例子是一个真实世界的例子,而且mongoose.connection.db.listCollections并没有清楚地定义如何应用解决方案。 - Steven Ventimiglia

0

这里还有另一种选择(稍微使用了 express,但是我认为没有用也可以正常工作),对我来说很管用。假设你导入了一个模型,而且假设 Blog 是你的模型名称。

const app = express();
const Blog = require('./models/blog');

app.post('/example', (req, res) => {
  Blog.findOne({name: 'collectionname'})
  .then(result => {
    if(result) {
      //If it exists
    }
  })
})

'''
result 可能是 null 或者 object


在这个例子中,搜索“'collectionname'”可能会让人感到困惑,因为那只是您博客的名称,而不是集合名称。但除此之外,这是一个有用的答案,谢谢! - Matt Browne

0
这在Mongoose 7+中运行得相当不错。
const findCollection = (collectionName) => {
  const collections = mongoose.connection.collections;
  let collectionFound = false;

  for (let collection in collections) {
    if (collection === collectionName) {
      collectionFound = true;
    }
  }

  return collectionFound;
};
然后你可以轻松地按照以下方式使用它:
if (findCollection("mycollection")) {
  console.log("COLLECTION EXISTS!");
} else {
  console.log("collection doesn't exist :(")
}
请注意,mongoose.connection.collections只提供特定MongoDB连接中可用的集合。这并不意味着您将返回数据库中的所有集合。如果您发现某些集合缺失,那只是意味着它们被其他连接处理,比如通过MongoDB Compass手动创建的集合。 另请参阅:Connection.prototype.collections

-8

在集合列表中查找集合

public function CollectionExists($collectionName)
    {
        $mongo = new Mongo();
        $collectionArr = $mongo->selectDB('yourrec')->listCollections();
        if (in_array($collectionName, $collectionArr)) {
            return true;
        }
        return false;
    }

4
使用的是 Node.js,而不是 PHP。 :( - Kino

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,