Làm cách nào để bạn sử dụng Mongoose mà không cần xác định lược đồ?


118

Trong các phiên bản trước của Mongoose (cho node.js), có một tùy chọn để sử dụng nó mà không cần xác định lược đồ

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

Nhưng trong phiên bản hiện tại, chức năng "noSchema" đã bị loại bỏ. Các lược đồ của tôi có thể thay đổi thường xuyên và thực sự không phù hợp với một lược đồ đã xác định, vậy có cách nào mới để sử dụng các mô hình ít lược đồ trong mongoose không?


3
chỉ cần sử dụng Mongodb trơn, giản đồ đó ít hơn theo mặc định
Simon Dragsbæk

Câu trả lời:


175

Tôi nghĩ đây là những gì bạn đang tìm kiếm Mongoose Nghiêm ngặt

tùy chọn: nghiêm ngặt

Tùy chọn nghiêm ngặt, (được bật theo mặc định), đảm bảo rằng các giá trị được thêm vào phiên bản mô hình của chúng tôi mà không được chỉ định trong lược đồ của chúng tôi sẽ không được lưu vào db.

Lưu ý: Không đặt thành false trừ khi bạn có lý do chính đáng.

    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
Bạn đã cứu ngày của tôi. Tôi cũng phát hiện ra rằng phải này không được sử dụng với #markMotified ( '<columnname>')
allenhwkim

6
Tái bút: Bạn phải làm thing.set(key, value)thing.key=valuekhông hoạt động với phương pháp này, tức là nó không tiếp tục thay đổi trong cơ sở dữ liệu nếu không.
laggingreflex

4
Nếu bạn sử dụng phương pháp này, bạn sẽ gặp sự cố khi truy xuất tài liệu. Sau khi thực hiện tìm kiếm và sau đó doc.someProp doc.someProp sẽ không được xác định, mặc dù nó thực sự ở đó trên đối tượng (console.log xác nhận điều này), điều này là do mongoose xác định các getters của riêng nó dường như chỉ hoạt động nếu bạn xác định hỗ trợ trên giản đồ
Melbourne2991

1
@ a20: Tôi hiểu bạn nói gì MySQL:) Và tôi nghĩ Jonathan gợi ý / theo Mongoose API Docs Lưu ý: Đừng đặt thành false trừ khi bạn có lý do chính đáng . Là hoàn toàn tốt với bối cảnh hiện nay (khoảng chỉ NO-SQL)
Amol M Kulkarni

2
@ Melbourne2991 điều này đúng ở một mức độ nào đó, tuy nhiên tôi đã tìm thấy một cách giải quyết. Bạn có thể gọi phương thức toJSON () trên tài liệu mà bạn đã truy xuất, phương thức này sau đó sẽ cho phép bạn sử dụng ký hiệu dấu chấm thông thường như doc.someProp. Xin lỗi để trả lời một câu trả lời cũ như vậy. Chỉ muốn thêm điều này trong trường hợp ai đó gặp phải điều tương tự. https://mongoosejs.com/docs/guide.html#toJSON
Chris

60

Trên thực tế, Schema.Types.Mixedchế độ "Hỗn hợp" ( ) dường như thực hiện chính xác điều đó trong Mongoose ...

nó chấp nhận một đối tượng JS dạng tự do , không có giản đồ - vì vậy bạn có thể ném bất cứ thứ gì vào nó. Có vẻ như bạn phải kích hoạt lưu trên đối tượng đó theo cách thủ công sau đó, nhưng nó có vẻ như là một sự cân bằng công bằng.

Trộn

Một SchemaType "bất cứ điều gì xảy ra", tính linh hoạt của nó đi kèm với việc đánh đổi là khó duy trì hơn. Hỗn hợp có sẵn hoặc thông qua Schema.Types.Mixedhoặc bằng cách chuyển một đối tượng rỗng theo nghĩa đen. Sau đây là tương đương:

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

Vì đây là kiểu không có giản đồ nên bạn có thể thay đổi giá trị thành bất kỳ thứ gì khác mà bạn thích, nhưng Mongoose mất khả năng tự động phát hiện và lưu những thay đổi đó. Để "nói" với Mongoose rằng giá trị của kiểu Hỗn hợp đã thay đổi, hãy gọi .markModified(path)phương thức của tài liệu chuyển đường dẫn đến kiểu Hỗn hợp mà bạn vừa thay đổi.

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

Đây có còn là cách phù hợp để làm việc ít lược đồ với Mongo / Mongoose không?
a20

5
Nhưng cấu trúc này lồng toàn bộ đối tượng dưới anytrường, vì vậy trên thực tế, nó có một lược đồ. Câu trả lời tốt hơn cho OP là sử dụng strict: falsenhư câu trả lời này nói.
steampowered

16

Này Chris, hãy nhìn vào Mongous . Tôi đang gặp vấn đề tương tự với mongoose, vì các Lược đồ của tôi thay đổi cực kỳ thường xuyên ngay trong quá trình phát triển. Mongous cho phép tôi có được sự đơn giản của Mongoose, đồng thời có thể xác định và thay đổi 'lược đồ' của mình một cách lỏng lẻo. Tôi đã chọn đơn giản là xây dựng các đối tượng JavaScript tiêu chuẩn và lưu trữ chúng trong cơ sở dữ liệu như vậy

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

Đơn giản hơn nhiều so với Mongoose, mặc dù tôi tin rằng bạn bỏ lỡ một số công cụ trung gian thú vị như "pre". Tôi không cần bất kỳ thứ đó. Hi vọng điêu nay co ich!!!


1
Bạn có biết cách xử lý các lỗi tình cờ trong mongous không? Điều này hơi bị thiếu trong tài liệu.
Erik Aigner

4
Tuy nhiên, tôi không xem đây là câu trả lời thực sự cho câu hỏi, @kwhitley có câu trả lời thích hợp liên quan đến Mongoose.
janex

Tôi sẽ phải đồng ý. Tuy nhiên, tôi không chắc rằng Schema.types.mixed có sẵn tại thời điểm OP đặt câu hỏi này
Hacknightly

OP ở đây, tôi có xu hướng đồng ý với bạn, tuy nhiên, câu trả lời đã đến một năm sau khi tôi chấp nhận câu trả lời này.
Christopher Tarquini

1

Đây là mô tả chi tiết: [ 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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.