คุณใช้ Mongoose โดยไม่กำหนดสคีมาได้อย่างไร?


118

ในเวอร์ชันก่อนหน้าของ Mongoose (สำหรับ node.js) มีตัวเลือกให้ใช้โดยไม่ต้องกำหนดสคีมา

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

แต่ในเวอร์ชันปัจจุบันฟังก์ชัน "noSchema" ได้ถูกลบออกไป สคีมาของฉันมีแนวโน้มที่จะเปลี่ยนแปลงบ่อยครั้งและไม่เข้ากับสคีมาที่กำหนดไว้ดังนั้นจึงมีวิธีใหม่ในการใช้โมเดลที่ไม่มีสคีมาในพังพอนหรือไม่


3
เพียงใช้ Mongodb ธรรมดานั่นคือสคีมาน้อยลงโดยค่าเริ่มต้น
Simon Dragsbæk

วิธีการรวบรวมของ createConnection () instane เป็นอย่างไร
Arnav Singh

คำตอบ:


175

ฉันคิดว่านี่คือสิ่งที่คุณกำลังมองหาพังพอนเข้มงวด

ตัวเลือก: เข้มงวด

ตัวเลือกที่เข้มงวด (เปิดใช้งานโดยค่าเริ่มต้น) ช่วยให้มั่นใจได้ว่าค่าที่เพิ่มในอินสแตนซ์โมเดลของเราที่ไม่ได้ระบุไว้ในสคีมาของเราจะไม่ถูกบันทึกลงในฐานข้อมูล

หมายเหตุ: อย่าตั้งค่าเป็นเท็จเว้นแต่คุณจะมีเหตุผลที่ดี

    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
คุณช่วยวันของฉัน ฉันยังพบว่าสิ่งนี้จะต้องไม่ใช้กับ #markMotified ('<columnName>')
allenhwkim

6
PS: คุณต้องทำthing.set(key, value)เพราะthing.key=valueใช้วิธีนี้ไม่ได้นั่นคือมันจะไม่เปลี่ยนแปลงในฐานข้อมูลอย่างอื่น
laggingreflex

4
หากคุณใช้วิธีนี้คุณจะพบปัญหาเมื่อเรียกเอกสาร หลังจากทำการค้นหาแล้ว doc.someProp doc.someProp จะไม่ถูกกำหนดแม้ว่าจะมีอยู่จริงในวัตถุ (console.log ยืนยันสิ่งนี้) เนื่องจากพังพอนกำหนด getters ของตัวเองซึ่งดูเหมือนจะใช้ได้เฉพาะเมื่อคุณกำหนด ข้อเสนอในสคีมา
Melbourne2991

1
@ A20: ผมเข้าใจสิ่งที่คุณพูดเกี่ยวกับMySQL:) และผมคิดว่าโจนาธานข้อเสนอแนะ / เป็นต่อพังพอน API เอกสาร หมายเหตุ: อย่าตั้งค่าเป็นเท็จถ้าคุณมีเหตุผลที่ดี ใช้ได้ดีกับบริบทปัจจุบัน (เกี่ยวกับเท่านั้นNO-SQL)
Amol M Kulkarni

2
@ Melbourne2991 นี่เป็นเรื่องจริง แต่มีวิธีแก้ปัญหาที่พบ คุณสามารถเรียกใช้เมธอด toJSON () บนเอกสารที่คุณดึงมาซึ่งจะช่วยให้คุณใช้สัญกรณ์จุดปกติของคุณเช่น doc.someProp ขออภัยที่ตอบกลับคำตอบเก่า ๆ แค่อยากจะเพิ่มสิ่งนี้ในกรณีที่มีคนเจอสิ่งเดียวกัน https://mongoosejs.com/docs/guide.html#toJSON
Chris

60

จริงๆแล้วSchema.Types.Mixedโหมด"ผสม" ( ) ดูเหมือนจะทำแบบนั้นในพังพอน ...

มันยอมรับคีมาน้อย , แบบอิสระ JS วัตถุ - ดังนั้นสิ่งที่คุณสามารถโยนมัน ดูเหมือนว่าคุณจะต้องทริกเกอร์การบันทึกบนวัตถุนั้นด้วยตนเองในภายหลัง แต่ดูเหมือนเป็นการแลกเปลี่ยนที่ยุติธรรม

ผสม

SchemaType "อะไรก็ได้" ความยืดหยุ่นของมันมาพร้อมกับการแลกเปลี่ยนที่ยากต่อการบำรุงรักษา ผสมสามารถใช้ได้ทั้งผ่าน Schema.Types.Mixedหรือโดยการส่งผ่านตัวอักษรวัตถุว่างเปล่า สิ่งต่อไปนี้เทียบเท่า:

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

เนื่องจากเป็นประเภทที่ไม่ใช้สคีมาคุณจึงสามารถเปลี่ยนค่าเป็นอย่างอื่นที่คุณต้องการได้ แต่พังพอนสูญเสียความสามารถในการตรวจจับและบันทึกการเปลี่ยนแปลงเหล่านั้นโดยอัตโนมัติ หากต้องการ "บอก" พังพอนว่าค่าของประเภทผสมมีการเปลี่ยนแปลงให้เรียกใช้.markModified(path)วิธีการของเอกสารที่ส่งเส้นทางไปยังประเภทผสมที่คุณเพิ่งเปลี่ยน

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

นี่ยังเป็นวิธีที่ถูกต้องในการทำงานกับ Mongo / Mongoose หรือไม่?
20

5
แต่โครงสร้างนี้ทำรังวัตถุทั้งหมดไว้ใต้anyฟิลด์ดังนั้นในความเป็นจริงมันจึงมีสคีมา คำตอบที่ดีกว่าสำหรับ OP คือใช้strict: falseตามคำตอบนี้
นึ่ง

16

เฮ้คริสดูที่Mongous ฉันมีปัญหาเดียวกันกับพังพอนเนื่องจาก Schemas ของฉันมีการเปลี่ยนแปลงบ่อยมากในขณะนี้ในการพัฒนา Mongous ทำให้ฉันมีความเรียบง่ายของพังพอนในขณะที่สามารถกำหนดและเปลี่ยนแปลง 'แผนผัง' ของฉันได้อย่างอิสระ ฉันเลือกที่จะสร้างออบเจ็กต์ JavaScript มาตรฐานและเก็บไว้ในฐานข้อมูลเช่นนั้น

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

ง่ายกว่าพังพอนแม้ว่าฉันเชื่อว่าคุณพลาดสิ่งที่เป็นตัวกลางเจ๋ง ๆ เช่น "pre" ฉันไม่ต้องการสิ่งนั้นเลย หวังว่านี่จะช่วยได้ !!!


1
คุณรู้วิธีที่จะจัดการกับความผิดพลาดในmongousโดยบังเอิญ? สิ่งนี้ขาดหายไปในเอกสาร
Erik Aigner

4
ฉันไม่เห็นว่านี่เป็นคำตอบที่แท้จริงสำหรับคำถาม แต่ @kwhitley มีคำตอบที่เหมาะสมเกี่ยวกับพังพอน
janex

ฉันจะต้องเห็นด้วย ฉันไม่แน่ใจว่า Schema.types.mixed นั้นมีให้บริการในเวลาที่ OP ถามคำถามนี้
Hacknightly

OP ที่นี่ฉันมีแนวโน้มที่จะเห็นด้วยกับคุณอย่างไรก็ตามคำตอบมาหนึ่งปีหลังจากที่ฉันยอมรับคำตอบนี้แล้ว
Christopher Tarquini

1

นี่คือคำอธิบายรายละเอียด: [ 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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.