¿Cómo se usa Mongoose sin definir un esquema?


118

En versiones anteriores de Mongoose (para node.js) había una opción para usarlo sin definir un esquema

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

Pero en la versión actual se ha eliminado la función "noSchema". Es probable que mis esquemas cambien a menudo y realmente no encajen con un esquema definido, entonces, ¿hay una nueva forma de usar modelos sin esquema en mangosta?


3
solo use Mongodb plain, eso es menos esquema por defecto
Simon Dragsbæk

Respuestas:


175

Creo que esto es lo que estás buscando Mongoose Strict

opción: estricta

La opción estricta, (habilitada por defecto), asegura que los valores agregados a nuestra instancia de modelo que no fueron especificados en nuestro esquema no se guarden en la base de datos.

Nota: No establezca el valor falso a menos que tenga una buena razón.

    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
Salvaste mi día. También descubrí que esto no debe usarse con #markMotified ('<columnName>')
allenhwkim

6
PD: Tienes que hacerlo thing.set(key, value)porque thing.key=valueno funciona con este método, es decir, no persiste cambiado en la base de datos de otra manera.
laggingreflex

4
Si usa este método, tendrá problemas al recuperar los documentos. Después de hacer una búsqueda y luego doc.someProp, doc.someProp no estará definido, aunque en realidad está allí en el objeto (un console.log confirma esto), esto se debe a que mongoose define sus propios captadores que parecen funcionar solo si usted define ese apoyo en el esquema
Melbourne2991

1
@ a20: Entiendo lo que dices sobre MySQL:) Y creo que la sugerencia de Jonathan / según Documentos de API de Mongoose Nota: No establezcas como falso a menos que tengas una buena razón . Está absolutamente bien con el contexto actual (solo aproximadamente NO-SQL)
Amol M Kulkarni

2
@ Melbourne2991 esto es cierto hasta cierto punto, sin embargo, hay una solución que encontré. Puede llamar al método toJSON () en el documento que recuperó, lo que le permitirá usar su notación de puntos habitual como doc.someProp. Lamento responder con una respuesta tan antigua. Solo quería agregar esto en caso de que alguien se encuentre con lo mismo. https://mongoosejs.com/docs/guide.html#toJSON
Chris

60

En realidad, el modo "Mixto" ( Schema.Types.Mixed) parece hacer exactamente eso en Mongoose ...

acepta un objeto JS de forma libre y sin esquema , por lo que cualquier cosa que pueda lanzarle. Parece que tienes que activar los guardados en ese objeto manualmente después, pero parece una compensación justa.

Mezclado

Un SchemaType de "todo vale", su flexibilidad viene con una compensación de que es más difícil de mantener. Mixed está disponible mediante Schema.Types.Mixedo pasando un literal de objeto vacío. Los siguientes son equivalentes:

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

Dado que es un tipo sin esquema, puede cambiar el valor a cualquier otra cosa que desee, pero Mongoose pierde la capacidad de detectar y guardar automáticamente esos cambios. Para "decirle" a Mongoose que el valor de un tipo Mixto ha cambiado, llame al .markModified(path)método del documento que pasa la ruta al tipo Mixto que acaba de cambiar.

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

¿Sigue siendo esta la forma correcta de trabajar sin esquema con Mongo / Mongoose?
a20

5
Pero esta estructura anida todo el objeto debajo del anycampo, por lo que de hecho tiene un esquema. La mejor respuesta al OP es usar strict: falsecomo dice esta respuesta.
Steampowered

16

Hola Chris, échale un vistazo a Mongous . Tenía el mismo problema con la mangosta, ya que mis esquemas cambian con mucha frecuencia en este momento en el desarrollo. Mongous me permitió tener la simplicidad de Mongoose, al mismo tiempo que podía definir y cambiar libremente mis 'esquemas'. Elegí simplemente construir objetos JavaScript estándar y almacenarlos en la base de datos de esa manera

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

Mucho más simple que Mongoose, aunque creo que te pierdes algunas cosas interesantes de middleware como "pre". Aunque no necesitaba nada de eso. ¡¡¡Espero que esto ayude!!!


1
¿Sabes cómo manejar errores en mongous por casualidad? Esto falta un poco en los documentos.
Erik Aigner

4
Sin embargo, no veo esto como la respuesta real a la pregunta, @kwhitley tiene la respuesta adecuada con respecto a Mongoose.
janex

Tendría que estar de acuerdo. Sin embargo, no estoy seguro de que Schema.types.mixed estuviera disponible en el momento de OP haciendo esta pregunta
Hacknightly

OP aquí, me inclino a estar de acuerdo con usted, sin embargo, la respuesta llegó un año después de que ya había aceptado esta.
Christopher Tarquini

1

Aquí está la descripción de los detalles: [ 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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.