MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Tính toán giá trị bỏ qua cho bản ghi đã cho để phân trang được sắp xếp

Đây được gọi là "phân trang chuyển tiếp", là một khái niệm bạn có thể sử dụng để "trang hiệu quả" thông qua các kết quả theo hướng "chuyển tiếp" khi sử dụng các kết quả "được sắp xếp".

Đã bao gồm logic JavaScript (vì nó hoạt động trong shell), nhưng không khó để dịch.

Khái niệm chung:

{ "_id": 1, "a": 3 },
{ "_id": 2, "a": 3 },
{ "_id": 3, "a": 3 },
{ "_id": 4, "a": 2 },
{ "_id": 5, "a": 1 },
{ "_id": 6, "a": 0 }

Hãy coi những tài liệu "đã được sắp xếp" đó (về sự tin cậy) như một ví dụ về kết quả mà chúng tôi muốn "phân trang" thành "hai" mục trên mỗi trang.

Trong trường hợp đầu tiên, bạn làm điều gì đó như sau:

var lastVal = null,
    lastSeen = [];

db.collection.find().sort({ "a": -1 }).limit(2).forEach(function(doc) {
    if ( lastVal != doc.a ) {
        lastSeen = [];
    }
    lastVal = doc.a;
    lastSeen.push( doc._id );
    // do something useful with each document matched
});

Bây giờ những lastVal đó và lastSeen là thứ bạn lưu trữ trong thứ gì đó giống như "biến phiên" có thể được truy cập vào yêu cầu tiếp theo về ứng dụng web hoặc thứ gì đó tương tự nếu không.

Mặc dù vậy, những gì chúng nên chứa là giá trị cuối cùng mà bạn sắp xếp và danh sách _id "duy nhất" các giá trị được nhìn thấy vì giá trị đó không thay đổi. Do đó:

lastVal = 3,
lastSeen = [1,2];

Vấn đề là khi có yêu cầu về "trang tiếp theo" thì bạn muốn sử dụng các biến đó cho một cái gì đó như sau:

var lastVal = 3,
    lastSeen = [1,2];

db.collection.find({ 
    "_id": { "$nin": lastSeen }, 
    "a": { "$lte": lastVal }
}).sort({ "a": -1 }).limit(2).forEach(function(doc) {
    if ( lastVal != doc.a ) {
        lastSeen = [];
    }
    lastVal = doc.a;
    lastSeen.push( doc._id );
    // do something useful with each document matched
});

Điều đó có nghĩa là "loại trừ" tất cả các giá trị của _id được ghi lại trong lastSeen từ danh sách kết quả, cũng như đảm bảo rằng tất cả kết quả cần phải "nhỏ hơn hoặc bằng" (thứ tự giảm dần) lastVal được ghi lại cho trường sắp xếp "a".

Điều này mang lại hai kết quả tiếp theo trong bộ sưu tập:

{ "_id": 3, "a": 3 },
{ "_id": 4, "a": 2 },

Nhưng sau khi xử lý các giá trị của chúng tôi bây giờ trông như thế này:

lastVal = 2,
lastSeen = [4];

Vì vậy, bây giờ logic tuân theo rằng bạn không cần phải loại trừ _id khác các giá trị đã thấy trước đây vì bạn chỉ thực sự tìm kiếm các giá trị của "a" hơn là "nhỏ hơn hoặc bằng" lastVal và vì chỉ có "một" _id giá trị được nhìn thấy ở giá trị đó thì chỉ loại trừ giá trị đó.

Tất nhiên, điều này sẽ dẫn đến trang tiếp theo khi sử dụng mã tương tự như ở trên:

{ "_id": 5, "a": 1 },
{ "_id": 6, "a": 0 }

Đó là cách hiệu quả nhất để "chuyển tiếp trang" thông qua các kết quả nói chung và đặc biệt hữu ích để phân trang hiệu quả các kết quả "đã được sắp xếp".

Tuy nhiên, nếu bạn muốn "chuyển" đến trang 20 hoặc hành động tương tự ở bất kỳ giai đoạn nào thì điều này không dành cho bạn. Bạn bị mắc kẹt với .skip() truyền thống và .limit() để có thể thực hiện điều này theo "số trang" vì không có cách hợp lý nào khác để "tính toán" điều này.

Vì vậy, tất cả phụ thuộc vào cách ứng dụng của bạn đang triển khai "phân trang" và những gì bạn có thể sống cùng. .skip().limit() phương pháp tiếp cận mắc phải hiệu suất "bỏ qua" và có thể tránh được bằng cách sử dụng phương pháp ở đây.

Mặt khác, nếu bạn muốn "chuyển đến trang" thì "bỏ qua" là lựa chọn thực sự duy nhất của bạn trừ khi bạn muốn xây dựng "bộ nhớ cache" của các kết quả. Nhưng đó hoàn toàn là một vấn đề khác.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Công tắc MongoDB $

  2. Cách cải thiện hiệu suất chèn MongoDB

  3. Giúp xác định một công cụ GUI MongoDB tuyệt vời

  4. MongoDB 'không thể tìm thấy chỉ mục cho truy vấn $ geoNear'

  5. Tổng quan về quản lý người dùng MongoDB