Wie verwendet man Mongoose, ohne ein Schema zu definieren?

118

In früheren Versionen von Mongoose (für node.js) gab es eine Option, um es zu verwenden, ohne ein Schema zu definieren

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

In der aktuellen Version wurde die Funktion "noSchema" jedoch entfernt. Meine Schemata ändern sich wahrscheinlich häufig und passen wirklich nicht zu einem definierten Schema. Gibt es also eine neue Möglichkeit, schemalose Modelle in Mungos zu verwenden?

Christopher Tarquini
quelle
3
Verwenden Sie einfach Mongodb Plain, das ist standardmäßig weniger Schema
Simon Dragsbæk

Antworten:

175

Ich denke, das ist es, wonach du suchst. Mongoose Strict

Option: streng

Die strikte Option (standardmäßig aktiviert) stellt sicher, dass zu unserer Modellinstanz hinzugefügte Werte, die nicht in unserem Schema angegeben wurden, nicht in der Datenbank gespeichert werden.

Hinweis: Setzen Sie nicht auf false, es sei denn, Sie haben einen guten Grund.

    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!!
Jonathan P. Diaz
quelle
2
Du hast meinen Tag gerettet. Ich fand auch heraus, dass dies nicht mit #markMotified ('<columnName>')
allenhwkim
6
PS: Sie müssen tun, thing.set(key, value)weil thing.key=valuediese Methode nicht funktioniert, dh sie bleibt ansonsten nicht in der Datenbank geändert.
Laggingreflex
4
Wenn Sie diese Methode verwenden, treten beim Abrufen der Dokumente Probleme auf. Nach dem Suchen und dann doc.someProp ist doc.someProp undefiniert, obwohl es sich tatsächlich im Objekt befindet (ein console.log bestätigt dies). Dies liegt daran, dass Mungo seine eigenen Getter definiert, die nur zu funktionieren scheinen, wenn Sie sie definieren diese Requisite auf dem Schema
Melbourne2991
1
@ a20: Ich verstehe, worüber Sie sagen MySQL:) Und ich denke, Jonathan Vorschlag / gemäß Mongoose API Docs Hinweis: Setzen Sie nicht auf false, es sei denn, Sie haben einen guten Grund . Ist absolut in Ordnung mit dem aktuellen Kontext (ungefähr nur NO-SQL)
Amol M Kulkarni
2
@ Melbourne2991 Dies ist bis zu einem gewissen Grad wahr, es gibt jedoch eine Problemumgehung, die ich gefunden habe. Sie können die toJSON () -Methode für das abgerufene Dokument aufrufen, um dann Ihre reguläre Punktnotation wie doc.someProp zu verwenden. Tut mir leid, auf eine so alte Antwort zu antworten. Ich wollte dies nur hinzufügen, falls jemand auf dasselbe stößt. https://mongoosejs.com/docs/guide.html#toJSON
Chris
60

Tatsächlich Schema.Types.Mixedscheint der "Mixed" ( ) -Modus genau das in Mongoose zu tun ...

es nimmt ein Schema-weniger , Freiform - JS - Objekt - so , was Sie an ihn werfen können. Es scheint, dass Sie das Speichern dieses Objekts anschließend manuell auslösen müssen, aber es scheint ein fairer Kompromiss zu sein.

Gemischt

Ein "alles geht" SchemaType, dessen Flexibilität mit einem Kompromiss verbunden ist, dass es schwieriger zu warten ist. Mixed ist entweder durch Schema.Types.Mixedoder durch Übergeben eines leeren Objektliteral verfügbar . Folgendes ist äquivalent:

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

Da es sich um einen Typ ohne Schema handelt, können Sie den Wert nach Belieben ändern. Mongoose verliert jedoch die Fähigkeit, diese Änderungen automatisch zu erkennen und zu speichern. Um Mongoose mitzuteilen, dass sich der Wert eines gemischten Typs geändert hat, rufen Sie die .markModified(path)Methode des Dokuments auf, das den Pfad zu dem gerade geänderten gemischten Typ übergibt.

person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved
kwhitley
quelle
Ist dies immer noch der richtige Weg, um ohne Schema mit Mongo / Mongoose zu arbeiten?
a20
5
Diese Struktur verschachtelt jedoch das gesamte Objekt unter dem anyFeld, sodass tatsächlich ein Schema vorhanden ist. Eine bessere Antwort auf das OP ist zu verwenden, strict: falsewie diese Antwort sagt.
Steampowered
15

Hey Chris, sieh dir Mongous an . Ich hatte das gleiche Problem mit Mungo, da sich meine Schemata gerade in der Entwicklung extrem häufig ändern. Mongous erlaubte mir, die Einfachheit von Mongoose zu haben, während ich meine 'Schemata' lose definieren und ändern konnte. Ich habe mich dafür entschieden, einfach Standard-JavaScript-Objekte zu erstellen und sie so in der Datenbank zu speichern

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

Weitaus einfacher als Mongoose, obwohl ich glaube, dass Sie einige coole Middleware-Sachen wie "pre" verpassen. Ich brauchte nichts davon. Hoffe das hilft!!!

Hacknightly
quelle
1
Wissen Sie, wie man zufällig mit Fehlern umgeht ? Dies fehlt in den Dokumenten etwas.
Erik Aigner
4
Ich sehe dies jedoch nicht als die wirkliche Antwort auf die Frage, @kwhitley hat die passende Antwort bezüglich Mungo.
Janex
Ich müsste zustimmen. Ich bin mir jedoch nicht sicher, ob Schema.types.mixed zum Zeitpunkt des OP verfügbar war und diese Frage stellte
Hacknightly
OP hier, ich bin geneigt, Ihnen zuzustimmen, aber die Antwort kam ein Jahr, nachdem ich diese bereits akzeptiert hatte.
Christopher Tarquini
1

Hier ist die Detailbeschreibung: [ 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
Vipul Panchal
quelle