Comment utiliser Mongoose sans définir de schéma?

118

Dans les versions précédentes de Mongoose (pour node.js), il y avait une option pour l'utiliser sans définir de schéma

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

Mais dans la version actuelle, la fonction "noSchema" a été supprimée. Mes schémas sont susceptibles de changer souvent et ne correspondent vraiment pas à un schéma défini, alors existe-t-il une nouvelle façon d'utiliser des modèles sans schéma dans la mangouste?

Christophe Tarquini
la source
3
il suffit d'utiliser Mongodb plain, thats schema less par défaut
Simon Dragsbæk

Réponses:

175

Je pense que c'est ce que tu cherches Mongoose Strict

option: strict

L'option stricte (activée par défaut) garantit que les valeurs ajoutées à notre instance de modèle qui n'ont pas été spécifiées dans notre schéma ne sont pas enregistrées dans la base de données.

Remarque: ne définissez pas sur false sauf si vous avez une bonne raison.

    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
la source
2
Tu as sauvé ma journée. J'ai également découvert que cela ne doit pas être utilisé avec #markMotified ('<columnName>')
allenhwkim
6
PS: Vous devez faire thing.set(key, value)car thing.key=valuene fonctionne pas avec cette méthode, c'est-à-dire qu'elle ne persiste pas modifiée dans la base de données sinon.
laggingreflex
4
Si vous utilisez cette méthode, vous rencontrerez des problèmes lors de la récupération des documents. Après avoir fait une recherche, puis doc.someProp doc.someProp sera indéfini, même s'il est réellement là sur l'objet (un console.log le confirme), c'est parce que mangouste définit ses propres getters qui semblent ne fonctionner que si vous définissez cet accessoire sur le schéma
Melbourne2991
1
@ a20: Je comprends ce que vous dites à propos de MySQL:) Et je pense que la suggestion de Jonathan / selon Mongoose API Docs Note: Ne définissez pas sur false sauf si vous avez une bonne raison . Est absolument d'accord avec le contexte actuel (à peu près seulement NO-SQL)
Amol M Kulkarni
2
@ Melbourne2991 c'est vrai dans une certaine mesure, mais il y a une solution de contournement que j'ai trouvée. Vous pouvez appeler la méthode toJSON () sur le document que vous avez récupéré, ce qui vous permettra ensuite d'utiliser votre notation par points régulière comme doc.someProp. Désolé de répondre sur une si vieille réponse. Je voulais juste ajouter ceci au cas où quelqu'un rencontrerait la même chose. https://mongoosejs.com/docs/guide.html#toJSON
Chris
60

En fait, le mode "Mixed" ( Schema.Types.Mixed) semble faire exactement cela dans Mongoose ...

il accepte un schéma moins , freeform objet JS - donc tout ce que vous pouvez jeter. Il semble que vous deviez déclencher manuellement des sauvegardes sur cet objet par la suite, mais cela semble être un compromis équitable.

Mixte

Un SchemaType «tout va bien», sa flexibilité vient en contrepartie du fait qu'il est plus difficile à maintenir. Mixed est disponible via Schema.Types.Mixedou en passant un littéral d'objet vide. Les éléments suivants sont équivalents:

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

Puisqu'il s'agit d'un type sans schéma, vous pouvez changer la valeur en tout ce que vous voulez, mais Mongoose perd la capacité de détecter et d'enregistrer automatiquement ces modifications. Pour "dire" à Mongoose que la valeur d'un type Mixte a changé, appelez la .markModified(path)méthode du document en passant le chemin vers le type Mixte que vous venez de modifier.

person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved
kwhitley
la source
Est-ce toujours la bonne façon de travailler sans schéma avec Mongo / Mongoose?
a20
5
Mais cette structure imbrique l'objet entier sous le anychamp, elle a donc en fait un schéma. La meilleure réponse au PO est d'utiliser strict: falsecomme cette réponse l'indique.
alimenté à vapeur
16

Hey Chris, regarde Mongous . J'avais le même problème avec la mangouste, car mes schémas changent extrêmement fréquemment en ce moment en cours de développement. Mongous m'a permis d'avoir la simplicité de Mongoose, tout en étant capable de définir et de modifier librement mes «schémas». J'ai choisi de créer simplement des objets JavaScript standard et de les stocker dans la base de données comme ceci

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

Bien plus simple que Mongoose, même si je pense que vous manquez des éléments de middleware sympas comme "pre". Je n'avais besoin de rien de tout ça. J'espère que cela t'aides!!!

Hacknightly
la source
1
Savez-vous comment gérer les erreurs de mongous par hasard? Cela manque quelque peu dans la documentation.
Erik Aigner
4
Je ne vois pas cela comme la vraie réponse à la question, @kwhitley a la réponse appropriée concernant Mongoose.
janex
Je suis d'accord. Je ne suis pas sûr, cependant, que Schema.types.mixed était disponible au moment de l'OP posant cette question
Hacknightly
OP ici, je suis enclin à être d'accord avec vous, cependant, la réponse est venue un an après que j'avais déjà accepté celle-ci.
Christopher Tarquini
1

Voici la description des détails: [ 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
la source