乐闻世界logo
搜索文章和话题

Mongoose 如何在不定义 schema 的情况下执行 mongoose 指令?

7 个月前提问
5 个月前修改
浏览次数93

6个答案

1
2
3
4
5
6

在 Mongoose 中,通常我们是通过定义一个 Schema 来指定集合中文档的结构,这样既可以确保数据的一致性,也方便开发者理解和操作数据库。然而,在某些情况下,我们可能需要在不定义 schema 的情况下执行操作,Mongoose 提供了这样的灵活性,通过所谓的“不严格”模式或者使用 mongoose.modelmongoose.connection 对象来直接操作。

如果想在不定义 schema 的情况下执行 Mongoose 指令,可以采用以下方法:

使用不严格模式的 Schema

即使你定义了一个 Schema,你也可以设置它为“不严格”模式,在这个模式下,Mongoose 不会限制数据的结构,允许存储任何形状的文档。

javascript
const mongoose = require('mongoose'); const { Schema } = mongoose; // 定义一个不严格的 Schema const anySchema = new Schema({}, { strict: false }); const AnyModel = mongoose.model('AnyCollection', anySchema); // 现在你可以存储任何形状的文档 const anyDocument = new AnyModel({ any: { thing: 'you want' } }); anyDocument.save();

使用 mongoose.modelmongoose.connection 对象

另外,你也可以不定义 Schema 而直接使用 mongoose.modelmongoose.connection 对象进行操作。

javascript
const mongoose = require('mongoose'); // 连接到数据库 mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true }); // 直接获取 Model,注意这里不需要定义 Schema const AnyModel = mongoose.model('AnyCollection', new mongoose.Schema({}, { strict: false })); // 通过 Model 创建并保存一个新文档 AnyModel.create({ any: { thing: 'you wish' } }, function (err, result) { if (err) throw err; // 执行一些其他操作 }); // 直接使用 mongoose.connection 对象操作数据库 const collection = mongoose.connection.collection('anycollection'); collection.insertOne({ anything: 'you want' }, function (err, result) { if (err) throw err; // 插入成功后的操作 });

在这些例子中,我们没有为 AnyCollection 定义 Schema,而是利用 Mongoose 提供的机制来执行操作。

不过需要注意的是,虽然这种方法提供了灵活性,但它也有缺点。没有 Schema 的 Mongoose 模型无法利用 Mongoose 提供的很多内置功能,如验证、中间件、静态方法等。此外,无法确保数据的一致性,这可能会导致一些意外的行为和难以调试的问题。所以在开发中应当权衡利弊,并在确实需要灵活性时才考虑不定义 Schema。

2024年6月29日 12:07 回复

I think this is what are you looking for Mongoose Strict

option: strict

The strict option, (enabled by default), ensures that values added to our model instance that were not specified in our schema do not get saved to the db.

Note: Do not set to false unless you have good reason.

shell
var thingSchema = new Schema({..}, { strict: false }); var Thing = mongoose.model('Thing', thingSchema); var thing = new Thing({ iAmNotInTheSchema: true }); thing.save() // iAmNotInTheSchema is now saved to the db!!
2024年6月29日 12:07 回复

Actually "Mixed" (Schema.Types.Mixed) mode appears to do exactly that in Mongoose...

it accepts a schema-less, freeform JS object - so whatever you can throw at it. It seems you have to trigger saves on that object manually afterwards, but it seems like a fair tradeoff.

Mixed

An "anything goes" SchemaType, its flexibility comes at a trade-off of it being harder to maintain. Mixed is available either through Schema.Types.Mixed or by passing an empty object literal. The following are equivalent:

shell
var Any = new Schema({ any: {} }); var Any = new Schema({ any: Schema.Types.Mixed });

Since it is a schema-less type, you can change the value to anything else you like, but Mongoose loses the ability to auto detect and save those changes. To "tell" Mongoose that the value of a Mixed type has changed, call the .markModified(path) method of the document passing the path to the Mixed type you just changed.

shell
person.anything = { x: [3, 4, { y: "changed" }] }; person.markModified('anything'); person.save(); // anything will now get saved
2024年6月29日 12:07 回复

Hey Chris, take a look at Mongous. I was having the same issue with mongoose, as my Schemas change extremely frequently right now in development. Mongous allowed me to have the simplicity of Mongoose, while being able to loosely define and change my 'schemas'. I chose to simply build out standard JavaScript objects and store them in the database like so

shell
function User(user){ this.name = user.name , this.age = user.age } app.post('save/user', function(req,res,next){ var u = new User(req.body) db('mydb.users').save(u) res.send(200) // that's it! You've saved a user });

Far more simple than Mongoose, although I do believe you miss out on some cool middleware stuff like "pre". I didn't need any of that though. Hope this helps!!!

2024年6月29日 12:07 回复

Here is the details description: [https://www.meanstack.site/2020/01/save-data-to-mongodb-without-defining.html][1]

shell
const express = require('express')() const mongoose = require('mongoose') const bodyParser = require('body-parser') const Schema = mongoose.Schema express.post('/', async (req, res) => { // strict false will allow you to save document which is coming from the req.body const testCollectionSchema = new Schema({}, { strict: false }) const TestCollection = mongoose.model('test_collection', testCollectionSchema) let body = req.body const testCollectionData = new TestCollection(body) await testCollectionData.save() return res.send({ "msg": "Data Saved Successfully" }) }) [1]: https://www.meanstack.site/2020/01/save-data-to-mongodb-without-defining.html
2024年6月29日 12:07 回复

You can also use mongoose.connection.collection

shell
import mongoose from 'mongoose'; const collection = mongoose.connection.collection('user') // use it like a mongodb collection await collection.updateOne({ name: "name" }, { $set: { name: "new_name" } })

See mongoose documentation

2024年6月29日 12:07 回复

你的答案