使用Mongoose在不传递模式的情况下查询集合

36

我理解得对吗,如果我想查询一个集合,我需要执行以下步骤:

    var mongoose = require("mongoose");

mongoose.connect();

var db = mongoose.connection;

db.on('open', function callback () {

    var kittySchema = mongoose.Schema({
        name: String
    })

    var Kitten = mongoose.model('Kitten', kittySchema)


    Kitten.find(function (err, kittens) {
        console.log(kittens);
    })

});

即使已经有一组小猫存在,我是否每次都需要指定模式?

为什么我不能像db.Kittens.find()这样做?


1
db.Kittens.find() 将是同步的。 - Sleiman Jneidi
5个回答

48

从Mongoose首页得知:

Mongoose提供了一种基于模式的简单解决方案,用于建模应用程序数据,并内置类型转换、验证、查询构建、业务逻辑钩子等功能。

Mongoose无法从一组可能唯一的文档中推断出模式。MongoDB不对存储在集合中的文档强制执行模式。

因此,Mongoose在NodeJS本地驱动程序(在此处)上添加了一层,许多人认为更加高效。然而,在使用Node.JS时使用MongoDB并不是必需的。

Mongoose需要两个基本要素才能工作:

  1. Schema == 这定义了文档结构(参考)。您可以添加验证、新方法、添加虚拟属性、使用数据类型、建立到其他集合(模型)的引用
  2. Model == 这是在运行时用于表达对集合的查询的类(参考)。一个Schema定义被用来构建一个Model。

因此,如您所见,在您复制的示例中,有一个kitten Schema定义,然后创建了一个Model Kitten。使用模式和模型的好处是Mongoose强制实施可用的属性/字段。

在应用程序中只需定义一次Schemas和Models,通常在应用程序启动时需要执行代码来定义它们,然后在整个应用程序生命周期中根据需要使用Model实例。

还有许多其他原因可能会使用Mongoose。

您完全可以使用更直接的方式,而不必使用模式,方法是使用NodeJS本地驱动程序。语法与您展示的类似,但稍微复杂一些:

MongoClient.connect("mongodb://localhost:27017/exampleDb", function(err, db) {
  if(err) { return console.dir(err); }

  var collection = db.collection('kittens');

    collection.find().toArray(function(err, kittens) {
        // here ...
    });    
});

不是简单的:

Kitten.find(function(err, kittens) {

});

此外,使用Mongoose时,你可能会发现编写和阅读更复杂的查询更容易:

Kitten.find().where('name', 'Harold').exec(/*callback*/);

我建议阅读更多文档以更好地了解该框架是否符合您的需求。不幸的是,文档有点零散,但如果您阅读 指南 标题下的子标题,您将获得很多有用的信息。


43

试试这个...

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const ProductSchema = new Schema({}, { strict: false });
const Product = mongoose.model('Product', ProductSchema, 'products');

module.exports = { Product };

9
这个回答违反了问题中的“不通过模式”部分,但它确实有效。它帮助我访问与更新后的模式相关的旧数据,以便将它们更新为新格式。谢谢。 - ruwan800

21

如果你想使用MongoDB但不使用模式(schemas),那么就不能使用Mongoose,应该使用类似mongodb的东西。


2
谢谢迄今为止。我想我的问题在于我发现mongoose的文档非常令人困惑。您介意简要解释一下模式和模型的术语以及它们如何共同工作吗? - user2422960

0

在我看来,如果您不需要模式,可以使用mongodb-nodejs驱动程序!

但在某些情况下:

  1. 您不想在存储库中维护模式,但仍要使用mongoose的附加功能(或)
  2. 您不想在代码片段/大型存储库中使用现有模式/创建新模式。

因此,在使用mongoose创建连接时,无需创建模式即可查询/写入mongoDB。以下代码使用mongoose创建连接,但不需要模式即可查询数据库!

注意:仅适用于mongoose版本<6

mongoose.connection.db.collection('collectionName', (err, collection) => {
    collection.find({}, {}, (err, document) => { /** .... */ })
})

mongoose 6版本于2021年底发布,建议使用最新版本,因为最新版本将提供更多功能(如果您的mongoDB服务器>5.0,则绝对需要v6,但如果mongoDB服务器版本<5.0,则不需要。 参考资料:mongoose-mongoDB-version-compatibility)。

注意:上述代码无法与mongoose版本>6一起使用的原因是mongoose在内部使用mongoDB-nodejs驱动程序与mongoDB服务器通信。 mongoose版本>6会带来mongoDB-nodejs驱动程序版本>4,在其中上述代码不再受支持,但存在替代方案。参考资料:Issue-Report/Ticket

使用的关键词:

mongoDB服务器:实际的Mongo数据库服务器。

MongoDB Node.js 驱动程序:这是一个可以用于从Node.js与MongoDB服务器通信的驱动程序。

Mongoose:Mongoose是一个对象数据建模(ODM)库,可通过Node.js访问MongoDB(使非关系型数据库MongoDB基于模式)。


-1
// With model
const model = await conn.model(modelName, schema, collectionName)
const documents = (await model.find({})).map(doc => doc._doc)

// Without model
const documents = await conn.db.collection('Apple').find().toArray()

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