- vừa được xem lúc

8 Mẹo hàng đầu khi sử dụng Prisma với MongoDB

0 0 2

Người đăng: Vinh Phạm

Theo Viblo Asia

Hôm nay, mình sẽ chia sẻ 8 mẹo quan trọng nhất khi sử dụng Prisma ORM với MongoDB. Nếu bạn đang xây dựng ứng dụng với MongoDB và muốn dùng Prisma làm ORM, có một số điểm quan trọng bạn cần lưu ý. MongoDB là cơ sở dữ liệu dạng tài liệu (document-based), hoạt động khác với các cơ sở dữ liệu quan hệ, và Prisma có những cách xử lý đặc thù cho những khác biệt này.

Mình đã làm việc nhiều năm với cả MongoDB và Prisma ORM, và đã tổng hợp lại những mẹo cốt lõi giúp bạn tiết kiệm hàng giờ gỡ lỗi và xây dựng ứng dụng hiệu quả hơn. Đây không chỉ là hướng dẫn cài đặt cơ bản — mà là những hiểu biết thực tế tạo ra sự khác biệt giữa một ứng dụng gặp trục trặc và một ứng dụng chạy mượt mà trong môi trường production.

Mẹo #1: Cấu hình MongoDB với replica set

MongoDB khi dùng với Prisma ORM phải được cấu hình thành một replica set. Đây không phải là tuỳ chọn — mà là bắt buộc. Prisma sử dụng transaction nội bộ để tránh ghi thiếu khi thực hiện các truy vấn lồng nhau, và MongoDB chỉ cho phép transaction trong môi trường replica set.

Nếu bạn cố dùng Prisma ORM với MongoDB dạng standalone (độc lập), bạn sẽ gặp lỗi: "Transactions are not supported by this deployment." — kể cả với thao tác đơn giản, vì Prisma bọc mọi thao tác trong transaction.

Giải pháp dễ nhất là sử dụng MongoDB Atlas, vốn hỗ trợ replica set mặc định (ngay cả gói miễn phí). Nếu phát triển local, bạn có thể chuyển MongoDB standalone sang replica set theo hướng dẫn trên trang chủ MongoDB.

Mẹo #2: Làm việc với các trường ObjectId

Trong MongoDB, khóa chính (primary key) thường là ObjectId nằm trong trường _id. Khi làm việc với Prisma ORM, bạn cần ánh xạ chính xác trường này trong schema:

Trường ObjectId trong Prisma phải là kiểu String hoặc Bytes

Phải có @db.ObjectId

Nên dùng @default(auto()) để tự sinh ID

Ví dụ mô hình với ObjectId:

model User { id String @id @default(auto()) @map("_id") @db.ObjectId email String name String?
}

Khi cần tạo ObjectId thủ công để test, dùng package bson:

import { ObjectId } from 'bson'
const id = new ObjectId()

Mẹo #3: Hiểu sự khác biệt giữa null và trường không tồn tại

MongoDB phân biệt rõ giữa các trường có giá trị null và những trường không tồn tại. Đây là một phần của tính năng "polymorphism" trong MongoDB — cho phép lưu nhiều kiểu dữ liệu khác nhau trong cùng một collection.

Ví dụ: Nếu bạn tạo bản ghi mà không truyền một trường tuỳ chọn, MongoDB sẽ không lưu trường đó. Nhưng Prisma ORM sẽ trả về giá trị null, khiến bạn tưởng rằng trường này có tồn tại và được gán null.

Khi lọc dữ liệu, nếu bạn chỉ lọc name: null, bạn chỉ tìm thấy các bản ghi mà name thực sự được set là null. Để bao gồm cả các bản ghi không có trường name, dùng toán tử isSet:

// Find records where name is either null or missing
const users = await prisma.user.findMany({ where: { OR: [ { name: null }, { name: { isSet: false } } ] }
})

Mẹo #4: Xử lý quan hệ đúng cách

MongoDB xử lý quan hệ bằng cách tham chiếu tài liệu hoặc nhúng tài liệu, khác hoàn toàn với khoá ngoại trong cơ sở dữ liệu quan hệ. Khi introspect MongoDB, Prisma có thể không tự động nhận biết các quan hệ.

Bạn cần tự thêm trường quan hệ trong schema. Ví dụ:

model Post { id String @id @default(auto()) @map("_id") @db.ObjectId title String userId String @db.ObjectId user User @relation(fields: [userId], references: [id])
} model User { id String @id @default(auto()) @map("_id") @db.ObjectId email String posts Post[]
}

Nhớ rằng các khoá tham chiếu tới tài liệu khác luôn cần @db.ObjectId.

Mẹo #5: Mô hình hóa tài liệu nhúng bằng type

MongoDB cho phép nhúng dữ liệu có cấu trúc vào trong một tài liệu — giúp giảm nhu cầu "join". Prisma ORM hỗ trợ mô hình này bằng từ khóa type.

  • type trong Prisma không tạo collection riêng mà chỉ mô tả cấu trúc nhúng.

Ví dụ:

type Address { street String city String state String zipCode String
} model Customer { id String @id @default(auto()) @map("_id") @db.ObjectId name String email String @unique address Address? // Embedded document addresses Address[] // Array of embedded documents
}

Sử dụng trong code:

// Creating a record with embedded document
const customer = await prisma.customer.create({ data: { name: 'Jane Smith', email: 'jane@example.com', address: { street: '123 Main St', city: 'Anytown', state: 'CA', zipCode: '12345' } }
}) // Querying with embedded fields
const californiaCustomers = await prisma.customer.findMany({ where: { address: { state: 'CA' } }
})

Tài liệu nhúng thích hợp khi:

  • Luôn truy xuất cùng tài liệu cha
  • Có mối quan hệ sở hữu rõ ràng (chỉ thuộc về một tài liệu cha)
  • Không cần truy vấn độc lập

Mẹo #6: Quản lý schema đơn giản với MongoDB

MongoDB có schema linh hoạt nên không cần migrate phức tạp. Bạn có thể thay đổi mô hình dữ liệu mà không downtime.

Dùng lệnh prisma db push để:

  • Tạo collection nếu chưa có
  • Thiết lập index cho các trường @unique
  • Cập nhật Prisma Client tự động

Mẹo #7: Một số lưu ý khi thiết kế

Một vài điểm quan trọng:

  • MongoDB chỉ dùng một trường _id làm khoá chính (không có @@id)
  • Dùng auto() với ObjectId, không dùng autoincrement()
  • Các quan hệ có vòng lặp nên dùng onDelete: NoAction để tránh lỗi
  • Kiểu Decimal128 trong MongoDB mới chỉ được Prisma hỗ trợ một phần

Biết rõ sự khác biệt giữa document DB và RDBMS giúp bạn thiết kế ứng dụng hiệu quả hơn.

Mẹo #8: Tối ưu hoá với collection lớn

Hiệu suất MongoDB có thể giảm nếu bạn không tối ưu khi sử dụng Prisma ORM. Một số mẹo:

  • Thêm @index cho trường thường truy vấn
  • Dùng select để chỉ lấy trường cần thiết
  • Dùng skiptake để phân trang
  • Dùng $runCommandRaw cho các truy vấn phức tạp hoặc pipeline

Ví dụ:

const users = await prisma.user.findMany({ where: { role: "ADMIN" }, select: { id: true, email: true }, // Only select needed fields take: 100, // Limit to 100 results skip: page * 100, // Pagination
})

Kết luận

Tám mẹo trên sẽ giúp bạn dùng Prisma ORM với MongoDB hiệu quả hơn và tránh các lỗi phổ biến. Hãy nhớ rằng MongoDB là cơ sở dữ liệu dạng tài liệu, khác biệt hoàn toàn với SQL, và hiểu rõ sự khác biệt này là chìa khoá để xây dựng ứng dụng hiệu năng cao.

Bạn có thể xem hướng dẫn đầy đủ cách xây dựng full-stack app với Next.js + Prisma + MongoDB để hiểu thêm.

Tóm tắt: Luôn dùng replica set, xử lý ObjectId chính xác, phân biệt null và trường thiếu, xử lý quan hệ đúng, dùng db push, tận dụng mô hình tài liệu của MongoDB, và tối ưu hóa truy vấn khi làm việc với dữ liệu lớn.

Cảm ơn các bạn đã theo dõi!

Bình luận

Bài viết tương tự

- vừa được xem lúc

TÌM HIỂU VỀ MONGODB

. 1. Định nghĩa về MongoDB. . MongoDB là một cơ sở dữ liệu mã nguồn mở và là cơ sở dữ liệu NoSQL(*) hàng đầu, được hàng triệu người sử dụng.

0 0 51

- vừa được xem lúc

Mongo DB cho người mới bắt đầu !

Lời nói đầu. Gần đây, mình mới bắt đầu nghiên cứu và sử dụng mongo db nên có chút kiến thức cơ bản về Mongo muốn share và note ra đây coi như để nhở (Biết đâu sẽ có ích cho ai đó).

0 0 37

- vừa được xem lúc

Áp dụng kiến trúc 3 Layer Architecture vào project NodeJS

The problem encountered. Các framework nodejs phổ biết như Express cho phép chúng ta dễ dàng tạo ra Resful API xử lí các request từ phía client một cách nhanh chóng và linh hoạt.

0 0 87

- vừa được xem lúc

Mongo DB cho người mới bắt đầu ! (P2)

Lời nói đầu. Gần đây, mình mới bắt đầu nghiên cứu và sử dụng mongo db nên có chút kiến thức cơ bản về Mongo muốn share và note ra đây coi như để nhở (Biết đâu sẽ có ích cho ai đó).

0 0 185

- vừa được xem lúc

Xây dựng CRUD RESTful API sử dụng Node, Express, MongoDB.

Introduction. Trong phạm vi bài viết này chúng ta sẽ cùng tìm hiểu về cách tạo restful api với Node, Express và MongoDB. . Xử lý các hoạt động crud.

0 0 228

- vừa được xem lúc

MongoDB là gì? Cơ sở dữ liệu phi quan hệ

Bài viết này mình sẽ giúp các bạn có cái nhìn tổng quan về MongoDB. Chúng ta không lạ gì với cơ sở dữ liệu quan hệ, còn với cơ sở dữ liệu phi quan hệ thì sao? MEAN stack (MongoDB, Express, AngularJS,

0 0 56