Hiểu và phân biệt document và model trong mongoose

Trước khi đọc bài này, bạn hãy chắc rằng đã biết về model trong mongoose. Trong mongoose document làm một ánh xạ one-to-one những record lưu trữ trong MongoDB.

Document và Model

Model cung cấp một constructor từ một Schema để khởi tạo một instance của document tương đương với một record trong database.

// File mongoose.document.js
// ... more code
const MyModel = mongoose.model('MyModel', new mongoose.Schema({name: String, age: Number}));

const doc = new MyModel();

console.log("Document is instanceof MyNodel: ", doc instanceof MyModel);
console.log("Document is instanceof MyNodel: ", doc instanceof mongoose.Model);
console.log("Document is instanceof MyNodel: ", doc instanceof mongoose.Document);
Run:
  • MacOS: ./node_modules/.bin/babel-node mongoose.document.js
  • Windows: .\node_modules\.bin\babel-node mongoose.document.js

Output:

Document is instanceof MyNodel: true
Document is instanceof MyNodel: true
Document is instanceof MyNodel: true

Làm thế nào để tạo ra document

Khi bạn truy vấn dữ liệu ví như findOne hoặc khởi tạo document từ model như ví dụ phần trên ta sẽ được một document.

// File mongoose.document.js
// ... more code
const getDocumentByFindOne = async () => {
    await new MyModel().save()
    const docFind = await MyModel.findOne();
    console.log("Document is instanceof MyNodel: ", docFind instanceof MyModel);
    console.log("Document is instanceof MyNodel: ", docFind instanceof mongoose.Model);
    console.log("Document is instanceof MyNodel: ", docFind instanceof mongoose.Document);
};

getDocumentByFindOne();
Run:
  • MacOS: ./node_modules/.bin/babel-node mongoose.document.js
  • Windows: .\node_modules\.bin\babel-node mongoose.document.js

Output:

Document is instanceof MyNodel: true
Document is instanceof MyNodel: true
Document is instanceof MyNodel: true

Update document

Để update document bạn có thể sử dụng vanilla javascript để update giá trị mới cho các field và gọi hàm save() để lưu dữ liệu mới update xuống database.

// File mongoose.document.js
// ... more code
const updateDocument = async () => {
    try {
        // Tạo và save new record xuống database
        await new MyModel({name: "HGA", age: 24}).save()
        // Tìm new record vừa được lưu xuống database 
        const docFind = await MyModel.findOne({name: "HGA"});

        // update age = 30
        docFind.age = 30;

        // update dữ liệu xuống database
        await docFind.save();

        // Kiểm tra dữ liệu
        console.log(await MyModel.findOne({name: "HGA"}));
    } catch(err) {
        console.log(err);
    }
    
};

updateDocument();
Run:
  • MacOS: ./node_modules/.bin/babel-node mongoose.document.js
  • Windows: .\node_modules\.bin\babel-node mongoose.document.js

Output: 

{ _id: 5dcefce3b793e72b983983ea, name: ‘HGA’, age: 30, __v: 0 }

Validate

Mỗi document sẽ được validate trước khi chúng được lưu xuống database. Nội bộ mongoose sẽ tự động gọi validate().

// File mongoose.document.js
// ... more code
const validate = async () => {
    const schema = new mongoose.Schema({ name: String, age: { type: Number, min: 0 } });
    const Person = mongoose.model('Person', schema);
    try {
        let p = new Person({ name: 'foo', age: 'bar' });
        // Cast to Number failed for value "bar" at path "age"
        await p.validate();
    } catch (err) {
        console.log("err: ", err);
    }

    try {
        let p2 = new Person({ name: 'foo', age: -1 });
        // Path `age` (-1) is less than minimum allowed value (0).
        await p2.validate();
    } catch (err) {
        console.log("err: ", err);
    }
}

validate();
Run:
  • MacOS: ./node_modules/.bin/babel-node mongoose.document.js
  • Windows: .\node_modules\.bin\babel-node mongoose.document.js

Output: 

ValidationError: Person validation failed: age: Cast to Number failed for value “bar” at path “age”

ValidationError: Person validation failed: age: Path `age` (-1) is less than minimum allowed value (0).

Overwriting

Để overwrite document trong mongoose (thay thế toàn bộ các key trong document) ta có 2 cách

Document.overwrite()

// File mongoose.document.js
// ... more code

const overwriting = async() => {
    const schema = new mongoose.Schema({ name: String, age: { type: Number, min: 0 } });
    const Person = mongoose.model('Person', schema);
    
    // Create new Person
    await new Person({name: "Deft", age: 18}).save();

    const doc = await Person.findOne({name: "Deft" });
    console.log("Origin: ", doc);

    // overwrite data 
    doc.overwrite({name: "haha"});
    let overwrite = await doc.save();

    console.log("overwrite", overwrite);
}

overwriting();
Run:
  • MacOS: ./node_modules/.bin/babel-node mongoose.document.js
  • Windows: .\node_modules\.bin\babel-node mongoose.document.js

Output: 

Origin: { _id: 5dcfb2801754ee3e9c1e47a2, name: ‘Deft’, age: 18, __v: 0 }
overwrite { _id: 5dcfb2801754ee3e9c1e47a2, name: ‘haha’, __v: 0 }

Model.replaceOne()

await Person.replaceOne({ name: "Deft" }, {name: "haha"} });
// Kết quả tương tự như trên

Kết

Document cùng với model, schema là những khái niệm cơ bản cốt lỗi nhất trong mongoose. Vậy nên mình mong muốn các bạn hiểu thật kỹ nó để chúng ta có thể đi xa hơn nắm trọn mongoose.

Source code demo

Các bạn nhớ đọc phần comment đầu tiên để chạy có được kết quả như mong muốn nhé.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x