2011-12-05 35 views
7

Tôi cần phải phân trang một tập hợp các bài báo (theo thứ tự theo ngày - và không có gì khác). Cách tiêu chuẩn làm một cái gì đó như thế này trong Mongodb là gì?Cách triển khai phân trang trong Mongodb?

Tôi sẽ không sử dụng phương thức skip() vì các vấn đề về hiệu suất. Tôi cũng không định sử dụng phương thức $ push. Phương pháp gần nhất tôi đã thấy là phương pháp truy vấn phạm vi. Nhưng có vẻ như thất bại nếu bất kỳ mục được sắp xếp nào bị xóa.

+2

chấp nhận câu trả lời và đóng câu hỏi này – beNerd

Trả lời

9

Sắp xếp phạm vi hoạt động tốt cho bạn. yêu cầu đầu tiên sẽ mất 10 hạng mục đầu tiên được sắp xếp theo ngày:

db.articles.find({}).sort({ date : -1 }).limit(10); 

Sau này, bạn sẽ cần phải lưu trữ ở đâu đó ngày mục cuối cùng và sử dụng id trong yêu cầu phân trang tiếp theo:

db.articles.find({"date": {$lt: storedDateOfLastItem}}).sort({ date : -1 }).limit(10); 

Vì vậy, tôi đoán nó nên làm việc tốt cho bạn. Để ước tính tổng số trang bạn cần sử dụng count.

Nhưng dường như không thành công nếu có bất kỳ mục được sắp xếp nào bị xóa.

Nếu bạn sẽ xóa bài viết ví dụ từ trang # 1, hãy chắc chắn rằng trang ngắt # 2 vì ngày cuối cùng được lưu trữ sẽ bị thay đổi. Để tránh điều này, bạn có thể ước tính số lượng mặt hàng trước ngày đã lưu hiện tại

db.articles.find({"date": {$gt: storedDateOfLastItem}}).sort({ date : -1 }).count() 

Nếu số này bị thay đổi (giả sử 2 đã bị loại bỏ). Bạn cần cập nhật storedDateOfLastItem

db.articles.find({"date": {$gt: storedDateOfLastItem}}).sort({ date : -1 }).take(2) 

Một lần nữa lưu trữDateOfLastItem từ mục cuối cùng trên yêu cầu và tiếp tục phân trang.

Nhưng ý kiến ​​của tôi chỉ giữ phân trang này vì nó không có logic bổ sung, bởi vì tôi cho rằng việc xóa bài viết là hoạt động hiếm.

Từ tài liệu MongoDB:

Chi phí Paging Thật không may bỏ qua có thể được (rất) tốn kém và đòi hỏi máy chủ để đi bộ từ đầu của bộ sưu tập, hoặc chỉ số, để có được để bù đắp vị trí/skip trước khi nó có thể bắt đầu trả lại trang của dữ liệu (giới hạn). Khi số trang tăng, bỏ qua sẽ trở nên chậm hơn và nhiều CPU hơn, và có thể IO bị ràng buộc, với các bộ sưu tập lớn hơn.

Phân trang dựa trên phạm vi cung cấp việc sử dụng chỉ mục tốt hơn nhưng không cho phép bạn dễ dàng chuyển đến một trang cụ thể.

+0

Truy vấn phạm vi/đánh dấu trang bằng cách sử dụng các loại ngày không hoạt động vì bạn sẽ nhận được sự không thống nhất cho nhiều bản ghi cùng ngày. Tôi sẽ sử dụng dấu giá trị _id thay thế cho điều này. Tất cả những gì đã nói đây là một tấn vệ sinh chỉ để tránh o (N) hiệu suất cho bỏ qua (N). –

+0

Ahhhh là phân trang rất tẻ nhạt trong mongodb? Tôi muốn một người nào đó từ 10Ge cho chúng tôi thấy cách họ đề nghị phân trang. –

+0

@LulZilla: Nhìn vào bản cập nhật của tôi, nó là từ tài liệu mongodb. –

0

Nếu bạn có thể sắp xếp theo chỉ mục, có thể triển khai phân trang hiệu quả bằng cách sử dụng công cụ sửa đổi truy vấn "$ phút" và "$ max" hoặc truy vấn phạm vi. Đảm bảo chỉ mục của bạn bao gồm thuộc tính duy nhất ở cuối (ví dụ: "_id").

Nếu bạn không thể sắp xếp chỉ mục, bạn có thể xử lý trước toàn bộ kết quả và giữ danh sách các giá trị "_id" theo thứ tự. Sau đó, bạn có thể lấy một phạm vi danh sách đó và tìm một trang kết quả bằng cách sử dụng toán tử truy vấn "$ in".

Các vấn đề liên quan