Como você usa o Mongoose sem definir um esquema?

118

Nas versões anteriores do Mongoose (para node.js), havia uma opção de usá-lo sem definir um esquema

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

Mas na versão atual a função "noSchema" foi removida. É provável que meus esquemas mudem com frequência e realmente não se encaixam em um esquema definido, então há uma nova maneira de usar modelos sem esquema no mangusto?

Christopher Tarquini
fonte
3
apenas use Mongodb plain, esse é o esquema menos por padrão
Simon Dragsbæk

Respostas:

175

Acho que é isso que você está procurando Mongoose Strict

opção: estrito

A opção estrita, (habilitada por padrão), garante que os valores adicionados à nossa instância de modelo que não foram especificados em nosso esquema não sejam salvos no banco de dados.

Nota: Não defina como falso a menos que você tenha um bom motivo.

    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
fonte
2
Você salvou meu dia. Também descobri que não deve ser usado com #markMotified ('<columnName>')
allenhwkim
6
PS: Você tem que fazer thing.set(key, value)porque thing.key=valuenão funciona com este método, ou seja, ele não persiste alterado no banco de dados de outra forma.
laggingreflex
4
Se você usar esse método, terá problemas ao recuperar os documentos. Depois de fazer um find e, em seguida, doc.someProp doc.someProp será indefinido, embora esteja realmente lá no objeto (um console.log confirma isso), isso é porque o mongoose define seus próprios getters que parecem funcionar apenas se você definir aquele suporte no esquema
Melbourne2991
1
@ a20: Eu entendo o que você diz sobre MySQL:) E acho que a sugestão do Jonathan / de acordo com o Mongoose API Docs Nota: Não defina como falso a menos que tenha um bom motivo . Está absolutamente bem com o contexto atual (cerca de apenas NO-SQL)
Amol M Kulkarni
2
@ Melbourne2991 isso é verdade até certo ponto, no entanto, há uma solução alternativa que encontrei. Você pode chamar o método toJSON () no documento que você recuperou, o que permitirá que você use sua notação de ponto regular como doc.someProp. Desculpe responder a uma resposta tão antiga. Só queria adicionar isso caso alguém se depare com a mesma coisa. https://mongoosejs.com/docs/guide.html#toJSON
Chris
60

Na verdade, o modo "Mixed" ( Schema.Types.Mixed) parece fazer exatamente isso no Mongoose ...

ele aceita um sem esquema , de forma livre JS objeto - de modo que você pode jogar nele. Parece que você tem que acionar salvamentos naquele objeto manualmente depois, mas parece uma troca justa.

Misturado

Um SchemaType "vale tudo", sua flexibilidade tem a desvantagem de ser mais difícil de manter. Mixed está disponível por meio de Schema.Types.Mixedou passando um literal de objeto vazio. Os seguintes são equivalentes:

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

Como é um tipo sem esquema, você pode alterar o valor para qualquer outro que desejar, mas o Mongoose perde a capacidade de detectar e salvar automaticamente essas alterações. Para "dizer" ao Mongoose que o valor de um tipo Mixed mudou, chame o .markModified(path)método do documento passando o caminho para o tipo Mixed que você acabou de alterar.

person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved
Kwhitley
fonte
Essa ainda é a maneira certa de trabalhar sem esquema com o Mongo / Mongoose?
a20 de
5
Mas essa estrutura aninha o objeto inteiro sob o anycampo, de modo que de fato tem um esquema. A melhor resposta ao OP é usar strict: falsecomo esta resposta diz.
movido a vapor em
16

Ei, Chris, dê uma olhada em Mongous . Eu estava tendo o mesmo problema com o mangusto, pois meus esquemas mudam com extrema frequência agora em desenvolvimento. Mongous me permitiu ter a simplicidade de Mongoose, enquanto era capaz de definir e alterar vagamente meus 'esquemas'. Eu escolhi simplesmente construir objetos JavaScript padrão e armazená-los no banco de dados assim

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

Muito mais simples do que o Mongoose, embora eu acredite que você perca algumas coisas legais de middleware como "pré". Eu não precisava de nada disso. Espero que isto ajude!!!

Hacknightly
fonte
1
Você sabe como lidar com erros em mongous por acaso? Isso está faltando um pouco nos documentos.
Erik Aigner
4
Não vejo isso como a resposta real para a pergunta, porém, @kwhitley tem a resposta apropriada sobre o Mongoose.
janeiro,
Eu tenho que concordar. Não tenho certeza, porém, se Schema.types.mixed estava disponível no momento do OP fazendo esta pergunta
Hacknightly,
OP aqui, estou inclinado a concordar com você, entretanto, a resposta veio um ano depois de eu já ter aceitado esta.
Christopher Tarquini,
1

Aqui está a descrição dos detalhes: [ 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
fonte