Giới thiệu về Mongoose cho MongoDB và Node.js

Mongoose là một framework JavaScript thường được dùng trong ứng dụng Node. js với database là MongoDB. Trong bài viết này, tôi sẽ ra mắt cho bạn Mongoose và MongoDB, và quan trọng hơn là đâu là nơi những công nghệ tiên tiến này tương thích với ứng dụng của bạn.

MongoDB là gì vậy?

Hãy mở màn với MongoDB. MongoDB là database ( một cơ sở tài liệu ) lưu tài liệu của bạn dưới dạng tài liệu. Thông thường, những tài liệu ( document ) này giống với cấu trúc giống như JSON :

Một document được đặt trong một collection. Ví dụ, và ví dụ document bên trên định nghĩa một đối tượng user. Đối tượng user này sau đó thường là một phần của collection được gọi là users.

Bạn đang đọc: Giới thiệu về Mongoose cho MongoDB và Node.js

Một trong những yếu tố quan trọng với MongoDB là tính linh hoạt trong cấu trúc của nó. Mặc dù trong ví dụ đầu tiên, đối tượng user chứa thuộc tính firstName và lastName, các thuộc tính này không bắt buộc trong mọi document của mỗi user, đó là một phần trong collection của users. Đây là điều làm cho MongoDB rất khác với các database SQL như MySQL hoặc Microsoft SQL Server, các database đó yêu cầu schema được định nghĩa rõ ràng cho từng đối tượng mà nó lưu trữ.

Giới thiệu về Mongoose cho MongoDB và Node.js

Khả năng tạo những dynamic object được tàng trữ dưới dạng documents trong database chính là lúc Mongoose hữu dụng.

Mongoose là gì vậy?

Mongoose là một Object Document Mapper ( ODM ). Điều này có nghĩa là Mongoose được cho phép bạn định nghĩa những object ( đối tượng người dùng ) với một schema được định nghĩa rõ ràng, được ánh xạ tới một MongoDB document. Mongoose phân phối một vài lượng đáng kinh ngạc những công dụng cho việc tạo ra và thao tác với những schema. Mongoose hiện có 8 SchemaTypes. Đó là :

StringNumberDateBufferBooleanMixedObjectIdArray

Mỗi loại tài liệu được cho phép bạn xác lập :

giá trị mặc địnhhàm xác thựccho biết một trường bắt buộchàm get cho phép bạn thao tác dữ liệu trước khi nó được trả về như một objecthàm set cho phép bạn thao tác dữ liệu trước khi nó được lưu vào cơ sở dữ liệutạo indexes cho phép dữ liệu được nạp nhanh hơn

Ngoài các tùy chọn phổ biến này, một vài kiểu dữ liệu nhất định cho phép bạn tùy chỉnh thêm cách dữ liệu được lưu trữ và truy xuất từ một database. Ví dụ, một kiểu dữ liệu String cũng cho phép bạn chỉ định các tùy chọn bổ sung sau đây:

chuyển đổi nó thành chữ thườngchuyển đổi nó thành chữ in hoacắt dữ liệu trước khi lưu lạimột biểu thức chính quy có thể giới hạn dữ liệu được phép lưu trong quá trình xác thựcmột enum có thể định nghĩa một danh sách các string (chuỗi) hợp lệ

Các thuộc tính Number and Date đều hỗ trợ chỉ định một giá trị tối thiểu và tối đa cho phép cho field đó.

Bạn nên quen thuộc với hầu hết 8 kiểu dữ liệu. Tuy vậy, có một vài ngoại lệ có thể xảy ra với bạn, chẳng hạn như Buffer, Mixed, ObjectId và Array.

Kiểu dữ liệu Buffer cho phép bạn lưu dữ liệu nhị phân. Một ví dụ phổ biến về dữ liệu nhị phân sẽ là hình ảnh hoặc tệp được mã hóa, chẳng hạn như tài liệu PDF.

Kiểu data Mixed biến thuộc một tính thành một field “anything goes” (thứ gì cũng được). Field này so sánh nhà phát triển có thể dùng MongoDB ra sao vì nó không có cấu trúc xác định. Hãy cảnh giác với việc dùng kiểu dữ liệu này vì bạn sẽ mất nhiều tính năng tuyệt vời mà Mongoose cung cấp, chẳng hạn như xác thực dữ liệu và phát hiện các thay đổi của entity để tự động biết để cập nhật thuộc tính khi lưu.

Kiểu dữ liệu ObjectId thường chỉ định một liên kết đến một tài liệu khác trong database của bạn. Ví dụ: nếu bạn có một bộ collection về books (sách) và author (tác giả), book document có thể chứa thuộc tính ObjectId có tham chiếu đến một author cụ thể của document.

Kiểu dữ liệu Array cho phép bạn lưu trữ các mảng giống như JavaScript. Với kiểu dữ liệu Array, bạn có thể thực hiện các chức năng phổ biến của JavaScript array, chẳng hạn như push, pop, shift, slice, và v.v.

Tóm tắt

Trước khi liên tục và tạo ra một vài ít code, tôi chỉ muốn tóm tắt lại những gì tất cả chúng ta vừa học được. MongoDB là một database được cho phép bạn tàng trữ những document với cấu trúc động. Các document này được lưu bên trong một collection. Mongoose là một thư viện JavaScript được cho phép bạn định nghĩa những schema với tài liệu được định kiểu rõ ràng. Khi một schema được định nghĩa, Mongoose được cho phép bạn tạo một Model dựa trên một schema đơn cử. Model của Mongoose sau đó được ánh xạ tới một MongoDB document trải qua định nghĩa schema của Model. Khi bạn đã xác lập những schema và Model của mình, Mongoose chứa nhiều hàm khác nhau được cho phép bạn xác nhận tính hợp lệ, lưu, xóa và truy vấn tài liệu của bạn bằng những hàm MongoDB thông dụng. Tôi sẽ nói về việc này nhiều hơn với những ví dụ code đơn cử.

Cài đặt MongoDB

Trước khi tất cả chúng ta hoàn toàn có thể mở màn tạo những schema và Mã Sản Phẩm của Mongoose, MongoDB phải được setup và thông số kỹ thuật. Tôi khuyến nghị bạn nên truy vấn trang TMongoDB’s Download page. Có 1 số ít tùy chọn khác nhau đã có sẵn để setup. Tôi đã link với Community Server. Điều này được cho phép bạn thiết lập một phiên bản đơn cử cho hệ quản lý và điều hành của bạn. MongoDB cũng cung ứng một Enterprise Server và tương hỗ thiết lập đám mây. Khi hàng loạt những cuốn sách hoàn toàn có thể được viết về việc thiết lập, kiểm soát và điều chỉnh và giám sát MongoDB, thì tôi sẽ bám chặt vào Community Server. Một khi bạn đã tải về và setup MongoDB cho hệ quản lý của bạn lựa chọn, bạn sẽ cần phải mở màn khởi động database. Tôi khuyên bạn nên truy vấn vào phần tài liệu của MongoDB về cách setup MongoDB Community Edition. Tôi sẽ đợi bạn thông số kỹ thuật MongoDB. Khi bạn đã chuẩn bị sẵn sàng, tất cả chúng ta hoàn toàn có thể chuyển sang thiết lập Mongoose để liên kết với database MongoDB vừa được setup của bạn.

Thiết lập Mongoose

Mongoose là một framework JavaScript, và tôi sẽ dùng trong một ứng dụng Node. js. Nếu bạn đã thiết lập Node. js, bạn hoàn toàn có thể chuyển sang bước tiếp theo. Nếu bạn chưa setup Node. js, tôi khuyên bạn nên khởi đầu bằng cách truy vấn trang Node. js Download page và chọn trình thiết lập cho hệ
quản lý của bạn. Với Node. js đã được thiết lập và sẵn sàng chuẩn bị hoạt động giải trí, tôi sẽ tạo một ứng dụng mới và sau đó setup Mongoose NPM Package. Với dấu nhắc lệnh được đặt ở nơi bạn muốn setup ứng dụng của mình, bạn hoàn toàn có thể chạy lệnh sau : Để khởi tạo ứng dụng của tôi, tôi để mọi thứ làm giá trị mặc định của chúng. Bây giờ tôi sẽ thiết lập gói mongoose như sau : Với tổng thể điều kiện kèm theo cần có đã được thông số kỹ thuật, tất cả chúng ta hãy liên kết với một database MongoDB. Tôi đã đặt đoạn code sau bên trong file index.js vì tôi đã chọn nó làm nơi khởi đầu cho ứng dụng của mình :

Dòng code đầu tiên gồm thư viện mongoose. Tiếp theo, tôi mở một kết nối đến database mà tôi gọi là mongoose_basics bằng cách dùng hàm connect.

Hàm connect chấp nhận hai tham số tùy chọn khác. Tham số thứ hai là đối tượng của các tùy chọn, ở đó bạn có thể định nghĩa username và password, nếu cần. Tham số thứ ba, cũng có thể là tham số thứ hai nếu bạn không có tùy chọn nào, là một hàm callback sau khi cố gắng kết nối. Hàm callback có thể được dùng theo một trong hai cách:

Để tránh phải trình làng về JavaScript Promises, tôi sẽ dùng cách tiên phong. Dưới đây là file index.js được update : Nếu có lỗi xảy ra khi liên kết với database, một exception sẽ được trả lại và toàn bộ những giải quyết và xử lý tiếp theo sẽ bị hoãn. Khi không có lỗi, tôi đã ghi lại một thông tin thành công xuất sắc đến console.

Mongoose bây giờ được thiết lập và kết nối với một cơ sở dữ liệu được gọi là mongoose_basics. Kết nối MongoDB của tôi không dùng username, password hoặc một port đặc biệt nào. Nếu bạn cần đặt các tùy chọn này hoặc bất kỳ tùy chọn nào khác trong khi kết nối, tôi khuyên bạn nên xem lại Mongoose Documentation on connecting. Tài liệu này giải thích chi tiết về nhiều tùy chọn có sẵn cũng như cách tạo nhiều kết nối, connection pooling, replicas, và v.v.

Với một liên kết thành công xuất sắc, tất cả chúng ta hãy chuyển sang định nghĩa một schema cho Mongoose.

Định nghĩa schema cho Mongoose

Trong phần giới thiệu, tôi đã cho thấy một đối tượng user có chứa hai thuộc tính: firstName và lastName. Trong ví dụ sau, tôi đã dịch document đó thành một schema của Mongoose:

Đây là một schema rất cơ bản chỉ chứa hai đặc tính mà không có thuộc tính nào liên kết với nó. Hãy mở rộng ví dụ này bằng cách chuyển đổi các thuộc tính tên và họ thành các đối tượng con của thuộc tính name. Thuộc tính name sẽ bao gồm cả tên và họ. Tôi cũng sẽ thêm một thuộc tính created theo kiểu Date.

Như bạn hoàn toàn có thể thấy, Mongoose được cho phép tôi tạo những schema rất linh động với nhiều tích hợp khả dĩ khác nhau theo cách tôi hoàn toàn có thể tổ chức triển khai data của mình.

Trong ví dụ tiếp theo này, tôi sẽ tạo ra hai schema mới để minh họa cách tạo mối quan hệ với một lược đồ khác: author và book. Schema của book sẽ chứa một tham chiếu đến schema của author.

Trên đây là schema của author đã mở rộng dựa trên các khái niệm schema của user mà tôi đã tạo trong ví dụ trước. Để liên kết Author và Book với nhau, thuộc tính đầu tiên của schema của author là một thuộc tính _id, và đó kiểu schema ObjectId. _id là cú pháp phổ biến để tạo khóa chính trong Mongoose và MongoDB. Sau đó, giống như schema user, tôi đã định nghĩa một thuộc tính name có chứa tên và họ của tác giả.

Mở rộng theo schema user, author chứa một vài loại schema theo kiểu String. Tôi cũng đã thêm một loại schema Buffer có thể chứa ảnh hồ sơ của author. Thuộc tính cuối cùng là ngày tạo ra author; tuy nhiên, bạn có thể nhận thấy nó được tạo ra hơi khác vì nó đã có một giá trị mặc định đã được xác định “now”. Khi author được lưu vào database, thuộc tính này sẽ được đặt thành date/time hiện tại.

Để hoàn thành các ví dụ schema, hãy tạo một schema của book có một tham chiếu đến author bằng cách dùng kiểu schema ObjectId:

Lược đồ book chứa một vài thuộc tính của kiểu String. Như đã đề cập ở trên, nó chứa một tham chiếu đến lược đồ author. Để minh họa thêm các định nghĩa schema mạnh mẽ, schema book cũng chứa một Array các ratings. Mỗi xếp hạng bao gồm summary, detail, numberOfStars, và createddate (ngày tạo ra).

Mongoose cho phép bạn tạo ra các schema có tham chiếu đến các schema khác, hoặc như trong ví dụ trên với thuộc tính ratings, nó cho phép bạn tạo một Array các thuộc tính con có thể chứa trong một schema có liên quan (như book đến author) hoặc nội tuyến như trong ví dụ trên (với book cho một Array ratings).

Tạo và lưu những model của Mongoose

Khi các schema của author và book chứng minh tính linh hoạt của Mongoose, tôi sẽ tiếp tục dùng các schema đó và lấy ra một model Author và Book từ chúng.

Một Model của Mongoose, khi được lưu lại, tạo một Document trong MongoDB với những thuộc tính như đã được định nghĩa từ schema mà nó bắt nguồn.

Để minh hoạ cho việc tạo và lưu một object, trong ví dụ tiếp theo này, tôi sẽ tạo ra một vài object: một Model Author và một vài Model cho Book. Khi được tạo ra, các object này sẽ được lưu lại thành MongoDB bằng cách dùng phương thức save của Model.

Trong ví dụ trên, tôi đã vô tình dẫn một tham chiếu đến hai cuốn sách mới đây nhất của tôi. Ví dụ bắt đầu bằng cách tạo và lưu một jamieObject được tạo ra từ một model Author. Bên trong hàm save của jamieObject, nếu một lỗi xảy ra, ứng dụng sẽ xuất ra một exception. Khi việc lưu lại thành công, bên trong hàm save, hai đối tượng book được tạo ra và lưu lại. Tương tự như jamieObject, nếu một lỗi xảy ra khi đang lưu, một lỗi được xuất ra; nếu không, thông báo thành công sẽ được xuất ra trong bảng điều khiển.

Để tạo tham chiếu tới Author, đối tượng book chỉ ra cả tham chiếu đến khóa chính _id của schema author trong thuộc tính author của lược đồ book.

Xác thực dữ liệu trước khi lưu lại

Khá phổ cập với những tài liệu mà sẽ \ tạo ra một Model được nhập vào bởi một form trên một website. Vì nguyên do này, bạn nên xác nhận tính hợp lệ của tài liệu này trước khi lưu Model vào MongoDB.

Trong ví dụ tiếp theo này, tôi đã cập nhật schema author trước đó để thêm xác nhận vào các thuộc tính sau: firstName,
twitter, facebook và linkedin.

Thuộc tính firstName đã được gán cho thuộc tính required. Bây giờ khi tôi gọi hàm save, Mongoose sẽ trả về một lỗi với một thông báo cho biết thuộc tính firstName là bắt buộc. Tôi đã chọn không cho thuộc tính lastName thành required trong trường hợp Cher hoặc Madonna là author trong database của tôi.

Các thuộc tính twitter, facebook và linkedin đều có các trình xác thực tùy chỉnh rất giống nhau được áp dụng cho chúng. Họ đảm bảo rằng các giá trị bắt đầu với tên miền tương ứng của các mạng xã hội. Các field này không bắt buộc, và vì vậy trình xác thực sẽ chỉ được áp dụng khi dữ liệu được cung cấp cho thuộc tính đó.

Tìm kiếm và cập nhật dữ liệu

Giới thiệu về Mongoose sẽ không hoàn hảo nếu không có ví dụ về tìm kiếm bản ghi ( record ) và update một hoặc nhiều thuộc tính trên đối tượng người dùng đó.

Mongoose cung cấp một vài chức năng khác nhau để tìm dữ liệu cho một Model cụ thể. Các hàm find, findOne và findById.

Hàm find và findOne đều chấp nhận một object làm đầu vào cho phép các tìm kiếm phức tạp, trong khi findById chỉ chấp nhận một giá trị duy nhất với hàm callback (sẽ có một ví dụ theo sau). Trong ví dụ tiếp theo này, tôi sẽ minh họa cách tìm tất cả các sách chứa string “mvc” trong tiêu đề.

Bên trong hàm find, tôi đang tìm kiếm chuỗi “mvc” không phân biệt chữ hoa chữ thường trong thuộc tính title. Điều này được thực hiện bằng cách dùng cú pháp giống với việc tìm một string với JavaScript.

Việc gọi hàm find cũng được liên kết với các phương thức truy vấn khác, chẳng hạn như where, and, or, limit, sort, any, và v.v.

Hãy lan rộng ra ví dụ trước nhằm mục đích số lượng giới hạn hiệu quả của tất cả chúng ta với năm book tiên phong và sắp xếp theo ngày tạo ( created date ) giảm dần. Nó sẽ trả về tối đa năm book gần đây nhất có chứa ” mvc ” trong tựa đề.

Sau khi áp dụng hàm find, thứ tự của các hàm khác không quan trọng vì tất cả các hàm có kết nối được biên dịch cùng nhau thành một truy vấn duy nhất và không được thực hiện cho đến khi hàm exec được gọi.

Như tôi đã đề cập trước đó, hàm findById được thực hiện hơi khác một chút. Hàm này thực hiện ngay lập tức và chấp nhận một hàm callback, thay vì cho phép một chuỗi kết nối các hàm. Trong ví dụ tiếp theo, tôi đang truy vấn một author cụ thể bằng _id của họ.

_id trong trường hợp của bạn có thể hơi khác. Tôi đã sao chép _id này từ một console.log trước đó khi tìm danh sách các book có “mvc” trong tựa đề.

Khi một object đã được trả về, bạn có thể sửa đổi bất kỳ thuộc tính nào của object đó để cập nhật. Khi bạn đã thực hiện các thay đổi cần thiết, bạn gọi phương thức save, giống như khi bạn đang tạo object. Trong ví dụ tiếp theo, tôi sẽ mở rộng ví dụ findbyId và cập nhật thuộc tính linkedin của author.

Sau khi một author được truy xuất thành công, thuộc tính linkedin được thiết lập và hàm save được gọi. Mongoose có thể phát hiện rằng thuộc tính linkedin đã được thay đổi và nó sẽ gửi một thông báo cập nhật tới MongoDB chỉ cho các thuộc tính đã được sửa đổi. Nếu xảy ra lỗi khi lưu, một exception sẽ được gửi đi và sẽ tạm dừng ứng dụng. Khi thành công, một thông báo thành công được ghi vào console.

Mongoose cũng cung cấp hai hàm bổ sung để tìm kiếm một đối tượng và lưu lại cùng lúc với các hàm được đặt tên khá phù hợp: findByIdAndUpdate và findOneAndUpdate. Hãy nâng cấp ví dụ trước để dùng findByIdAndUpdate.

Trong ví dụ trước, các thuộc tính để cập nhật được cung cấp dưới dạng một đối tượng cho tham số thứ hai của hàm findByIdAndUpdate. Hàm callback bây giờ là tham số thứ ba. Khi cập nhật thành công, object author được trả về có chứa thông tin đã được cập nhật. Điều này được ghi vào console để xem các thuộc tính đã được cập nhật của tác giả.

Ví dụ code sau tất cả

Trong suốt bài viết này, tôi đã phân phối những trích đoạn code nhỏ xác lập một hành vi rất đơn cử, và ví dụ điển hình như tạo schema, tạo Model, và v.v. Hãy tích hợp chúng lại với nhau trong một ví dụ không thiếu.

Đầu tiên, tôi đã tạo hai file bổ sung: author.js và book.js. Các tệp này chứa các định nghĩa schema tương ứng của chúng và việc tạo ra model. Dòng mã cuối cùng giúp cho model sẵn sàng để dùng trong file index.js.

Hãy mở màn với file author.js : Tiếp theo là file book.js : Và ở đầu cuối, file index.js được update :

Trong ví dụ trên, tất cả các hoạt động của Mongoose được chứa trong hàm connect. Các file author và book được bao kèm với hàm require sau khi liên kết với thư viện mongoose.

Với MongoDB đang chạy, giờ đây bạn hoàn toàn có thể triển khai xong ứng dụng Node. js vừa đủ bằng lệnh sau đây :

Sau khi tôi lưu một vài data vào database của mình, tôi đã cập nhật file index.js với các hàm find như sau:

Một lần nữa, bạn có thể chạy ứng dụng bằng lệnh: node index.js.

Tóm tắt

Sau khi đọc bài viết này, bạn sẽ hoàn toàn có thể tạo những Model và Schema cực kỳ linh động cho Mongose, và vận dụng xác thực đơn giản hoặc phức tạp, tạo và update tài liệu và ở đầu cuối tìm kiếm những tài liệu đã được tạo. Hy vọng giờ đây bạn cảm thấy tự do khi dùng Mongoose. Nếu bạn đang tìm hiểu và khám phá thêm, tôi sẽ ý kiến đề nghị bạn xem những Mongoose Guides, những hướng dẫn này điều tra và nghiên cứu sâu hơn những chủ đề nâng cao như population, middleware, promises, và v.v. Happy hunting ( poor Mongoose animal reference ) !

Giới thiệu: Quang Sơn

Quang Sơn là giám đốc hocdauthau.com - Kênh thông tin học đấu thầu, kiến thức tổng hợp, công nghệ, đời sống.

0 Shares
Share
Tweet
Pin