スキーマを定義せずにMongooseをどのように使用しますか?


118

以前のバージョンのMongoose(node.js用)には、スキーマを定義せずにそれを使用するオプションがありました

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

ただし、現在のバージョンでは、「noSchema」関数は削除されています。私のスキーマは頻繁に変更される可能性が高く、定義されたスキーマに実際には適合しないので、マングースでスキーマのないモデルを使用する新しい方法はありますか?


3
Mongodbプレーンを使用するだけで、デフォルトではスキーマが少なくなります
SimonDragsbækMay

回答:


175

これはあなたがマングース・ストリクトを探しているものだと思います

オプション:厳格

strictオプション(デフォルトで有効)は、スキーマで指定されていないモデルインスタンスに追加された値がデータベースに保存されないようにします。

注:正当な理由がない限り、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

6
PS:この方法では機能しないthing.set(key, value)ため、実行する必要がありthing.key=valueます。それ以外の場合、データベースに変更が永続化されません。
laggingreflex 2015年

4
この方法を使用すると、ドキュメントを取得するときに問題が発生します。検索を行った後、doc.someProp doc.somePropは未定義になりますが、実際にはオブジェクト上にあります(console.logがこれを確認します)。これは、mongooseが独自のゲッターを定義しているためです。スキーマの小道具
Melbourne2991

1
@ A20:私はあなたについて言うことを理解MySQL:)と私は思うジョナサンあたりとして提案/ マングースAPIドキュメント 注:あなたが正当な理由がない限り、DOはfalseに設定されていません。現在のコンテキストで完全に問題ありません(約のみNO-SQL
Amol M Kulkarni 2016

2
@ Melbourne2991これはある程度正しいですが、私が見つけた回避策があります。取得したドキュメントでtoJSON()メソッドを呼び出すと、doc.somePropのような通常のドット表記を使用できます。そのような古い答えに返信して申し訳ありません。誰かが同じことに遭遇した場合に備えて、これを追加したかっただけです。https://mongoosejs.com/docs/guide.html#toJSON
Chris

60

実際、「混合」(Schema.Types.Mixed)モードは、マングースのそれとまったく同じように見えます...

それが受け入れ、スキーマレスフリーフォームのJSオブジェクトをので、あなたがそれで投げることができるものは何でも- 。その後、そのオブジェクトの保存を手動でトリガーする必要があるようですが、それは公平なトレードオフのようです。

混合

「何でもいい」SchemaTypeであり、その柔軟性は、維持するのが困難であるというトレードオフになります。MixedはSchema.Types.Mixed、空のオブジェクトリテラルを介して、または渡すことで使用できます 。以下は同等です。

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

スキーマレスタイプであるため、値を好きなように変更できますが、Mongooseはそれらの変更を自動検出して保存する機能を失います。混合型の値が変更されたことをMongooseに「伝える」には、変更.markModified(path)した混合型へのパスを渡すドキュメントのメソッドを呼び出します。

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

これは、Mongo / Mongooseでスキーマなしで作業するための正しい方法ですか?
a20 20

5
しかし、この構造はオブジェクト全体をanyフィールドの下にネストするため、実際にはスキーマを持っています。OPへのより良い答えは、使用することですstrict: false、この答えは言います。
15年

16

クリスさん、モンゴスを見てください。私のスキーマは現在開発中で非常に頻繁に変更されるため、私はマングースで同じ問題を抱えていました。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
});

Mongooseよりもはるかに単純ですが、「pre」などのクールなミドルウェア製品を見逃していると思います。私はそれを必要としませんでした。お役に立てれば!!!


1
あなたは偶然に巨大なエラーを処理する方法を知っていますか?これはドキュメントにいくらか欠けています。
エリックアイグナー2012

4
私はこれを質問に対する本当の答えとは思いませんが、@ kwhitleyはマングースに関して適切な答えを持っています。
janex 2013年

同意する必要があります。ただし、OPがこの質問をした時点でSchema.types.mixedが利用可能だったかどうかは
わかりませ

ここでOP、私はあなたに同意する傾向がありますが、答えはすでにこれを受け入れてから1年後のことです。
クリストファータルキーニ

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.