Jak używać Mongoose bez definiowania schematu?

118

W poprzednich wersjach Mongoose (dla node.js) istniała możliwość korzystania z niego bez definiowania schematu

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

Jednak w obecnej wersji funkcja „noSchema” została usunięta. Moje schematy mogą się często zmieniać i naprawdę nie pasują do zdefiniowanego schematu, więc czy istnieje nowy sposób korzystania z modeli bez schematu w Mongoose?

Christopher Tarquini
źródło
3
po prostu użyj zwykłego Mongodb, domyślnie jest to mniejszy schemat
Simon Dragsbæk

Odpowiedzi:

175

Myślę, że właśnie tego szukasz w przypadku Mongoose Strict

opcja: ścisła

Opcja ścisła (domyślnie włączona) zapewnia, że ​​wartości dodane do instancji naszego modelu, które nie zostały określone w naszym schemacie, nie zostaną zapisane w bazie danych.

Uwaga: nie ustawiaj na fałsz, chyba że masz dobry powód.

    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
źródło
2
Uratowałeś mi dzień. Dowiedziałem się również, że nie można tego używać z #markMotified ('<nazwa_kolumny>')
allenhwkim
6
PS: Musisz to zrobić, thing.set(key, value)ponieważ thing.key=valuenie działa z tą metodą, tj. W przeciwnym razie nie zostanie zmieniona w bazie danych.
laggingreflex
4
Jeśli użyjesz tej metody, napotkasz problemy podczas pobierania dokumentów. Po wykonaniu wyszukiwania, a następnie doc.someProp, doc.someProp będzie niezdefiniowany, nawet jeśli faktycznie znajduje się w obiekcie (potwierdza to console.log), dzieje się tak, ponieważ mongoose definiuje własne metody pobierające, które wydają się działać tylko wtedy, gdy zdefiniujesz ten rekwizyt na schemacie
Melbourne2991,
1
@ a20: Rozumiem, o czym mówisz MySQL:) I myślę, że sugestia Jonathana / zgodnie z dokumentami Mongoose API Uwaga: Nie ustawiaj na fałsz, chyba że masz dobry powód . Jest absolutnie w porządku z obecnym kontekstem (tylko o NO-SQL)
Amol M Kulkarni
2
@ Melbourne2991 jest to do pewnego stopnia prawdą, jednak istnieje obejście, które znalazłem. Możesz wywołać metodę toJSON () na pobranym dokumencie, co pozwoli ci użyć zwykłej notacji kropkowej, takiej jak doc.someProp. Przepraszam, że odpowiadam na tak starą odpowiedź. Chciałem tylko dodać to na wypadek, gdyby ktoś natknął się na tę samą rzecz. https://mongoosejs.com/docs/guide.html#toJSON
Chris
60

W rzeczywistości Schema.Types.Mixedtryb „mieszany” ( ) wydaje się robić dokładnie to samo w Mongoose ...

akceptuje pozbawiony schematu , dowolny obiekt JS - więc cokolwiek możesz na to rzucić. Wygląda na to, że musisz później ręcznie uruchomić zapisywanie tego obiektu, ale wydaje się, że jest to uczciwy kompromis.

Mieszany

SchemaType typu „wszystko idzie”, jego elastyczność wiąże się z tym, że trudniej jest go utrzymać. Mieszane jest dostępne za pośrednictwem Schema.Types.Mixedlub przez przekazanie pustego literału obiektu. Poniższe są równoważne:

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

Ponieważ jest to typ bez schematu, możesz zmienić wartość na dowolną inną, ale Mongoose traci możliwość automatycznego wykrywania i zapisywania tych zmian. Aby „powiedzieć” Mongoose, że zmieniła się wartość typu mieszanego, wywołaj .markModified(path)metodę dokumentu przekazującą ścieżkę do właśnie zmienionego typu mieszanego.

person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved
kwhitley
źródło
Czy nadal jest to właściwy sposób pracy bez schematu z Mongo / Mongoose?
a20
5
Ale ta struktura zagnieździ cały obiekt pod anypolem, więc w rzeczywistości ma schemat. Lepszą odpowiedzią na PO jest użycie, strict: falsejak mówi ta odpowiedź.
steampowered
16

Hej Chris, spójrz na Mongousa . Miałem ten sam problem z mangustą, ponieważ moje schematy zmieniają się niezwykle często w trakcie opracowywania. Mongous pozwolił mi mieć prostotę Mongoose, jednocześnie mogąc swobodnie definiować i zmieniać moje „schematy”. Zdecydowałem się po prostu zbudować standardowe obiekty JavaScript i przechowywać je w bazie danych w ten sposób

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

O wiele prostsze niż Mongoose, chociaż wierzę, że przegapisz kilka fajnych rzeczy, takich jak „pre”. Nie potrzebowałem tego jednak. Mam nadzieję że to pomoże!!!

Hacknightly
źródło
1
Czy wiesz, jak przez przypadek radzić sobie z błędami w mongusach ? Tego trochę brakuje w dokumentacji.
Erik Aigner,
4
Nie uważam tego za prawdziwą odpowiedź na to pytanie, @kwhitley ma odpowiednią odpowiedź dotyczącą Mongoose.
janex
Musiałbym się zgodzić. Nie jestem jednak pewien, czy Schema.types.mixed był dostępny w momencie, gdy OP zadawał to pytanie
Hacknightly
OP tutaj, jestem skłonny się z tobą zgodzić, jednak odpowiedź nadeszła rok po tym, jak już ją zaakceptowałem.
Christopher Tarquini,
1

Oto szczegółowy opis: [ 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
źródło