如何在不定义架构的情况下使用Mongoose?


118

在Mongoose的早期版本(针对node.js)中,可以选择使用它而不定义模式

var collection = mongoose.noSchema(db, "User");

但是在当前版本中,“ noSchema”功能已被删除。我的模式可能会经常更改,并且实际上不适合已定义的模式,因此,有没有一种新方法可以在猫鼬中使用无模式的模型?


3
只是使用MongoDB的平原,这就是模式较少默认
西蒙Dragsbæk

Answers:


175

我想这就是您要寻找猫鼬严密的东西

选项:严格

严格选项(默认情况下启用)可确保未在架构中指定的添加到模型实例的值不会保存到数据库中。

注意:除非有充分的理由,否则请勿将其设置为false。

    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!!

2
你救了我的日子。我还发现,不能与#markMotified('<columnName>')一起使用
allenhwkim 2013年

6
PS:您必须这样做,thing.set(key, value)因为thing.key=value不适用于此方法,也就是说,否则它不会持久地更改到数据库中。
laggingreflex

4
如果使用此方法,则在检索文档时会遇到问题。查找之后,然后doc.someProp doc.someProp仍将是未定义的,即使它实际上存在于对象上(console.log确认了这一点),这是因为猫鼬定义了自己的吸气剂,该吸气剂仅在您定义时才起作用模式上的那个道具
Melbourne2991

1
@ a20:我理解您在说什么MySQL:)而且我认为Jonathan建议/根据Mongoose API Docs 注意:除非您有充分的理由,否则请不要将其设置为false。在当前情况下(大约只是NO-SQL)是完全可以的
Amol M Kulkarni

2
@ Melbourne2991这在一定程度上是对的,但是我发现了一种解决方法。您可以在检索到的文档上调用toJSON()方法,然后该方法将允许您使用常规的点表示法,例如doc.someProp。很抱歉回答这么旧的答案。只是想添加此内容,以防有人遇到相同的事情。https://mongoosejs.com/docs/guide.html#toJSON
克里斯(Chris)

60

实际上,“混合”(Schema.Types.Mixed)模式似乎完全在猫鼬中实现了...

它接受一个无模式的自由格式的JS对象 -因此您可以抛出它。看来您之后必须手动触发该对象的保存,但这似乎是一个公平的权衡。

混合的

“随处可见” SchemaType,其灵活性来自于难以维护的折衷。混合可通过 Schema.Types.Mixed或通过传递空对象文字来使用。以下是等效的:

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

由于它是一种无模式类型,因此您可以将其值更改为其他任何值,但是Mongoose失去了自动检测和保存这些更改的功能。要“告诉”猫鼬混合类型的值已更改,请调用.markModified(path)文档的方法,将路径传递到刚更改的混合类型。

person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved

这仍然是使用Mongo / Mongoose进行无模式工作的正确方法吗?
2015年

5
但是此结构将整个对象嵌套在该any字段下,因此它实际上具有模式。更好的答案OP是使用strict: false作为本回答说。
蒸汽动力

15

嘿克里斯,看看Mongous。我遇到了猫鼬同样的问题,因为我的架构在开发中非常频繁地更改。Mongous使我能够拥有猫鼬的简单性,同时能够轻松地定义和更改我的“方案”。我选择简单地构建标准的JavaScript对象并将其存储在数据库中,如下所示

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
});

尽管我确实相信您会错过一些很酷的中间件,例如“ pre”,但它远比Mongoose简单。我不需要任何东西。希望这可以帮助!!!


1
你知道如何处理错误mongous的机会呢?这在文档中有些缺失。
埃里克·艾格纳

4
我不认为这是问题的真正答案,@ kwhitley对于猫鼬有适当的答案。
janex

我将不得不同意。不过,我不确定OP提出这个问题时是否可以使用Schema.types.mixed
Hacknightly,2013年

OP,我倾向于同意您的意见,但是,答案是在我已经接受这一答案之后的一年。
Christopher Tarquini 2014年

1

以下是详细说明:[ https://www.meanstack.site/2020/01/save-data-to-mongodb-without-defining.html] [1 ]

    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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.