獲取 MongoDB 中的最後 N 條記錄

Mehvish Ashiq 2022年6月7日
獲取 MongoDB 中的最後 N 條記錄

本教程將探討獲取 MongoDB 中最後 N 條記錄的方法數量,其中 N 為正數且大於零。我們將看到如何檢索有無排序的文件數量。

獲取 MongoDB 中的最後 N 條記錄

我們必須有一個包含文件的集合才能繼續實際示例。因此,讓我們繼續使用以下查詢來建立一個集合併在其中插入一些文件。

示例程式碼:

> use get_n_records;
> db.createCollection('stock');
> db.stock.insertMany([
    {"item": "abc", "quantity": 12},
    {"item": "def", "quantity": 234},
    {"item": "ghi", "quantity": 45},
    {"item": "jkl", "quantity": 345},
    {"item": "mno", "quantity": 243},
    {"item": "pqr", "quantity": 345},
    {"item": "stu", "quantity": 56},
    {"item": "vwx", "quantity": 575},
    {"item": "yzz", "quantity": 398}
]);
> db.stock.find();

輸出:

{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fe"), "item" : "jkl", "quantity" : 345 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75ff"), "item" : "mno", "quantity" : 243 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7600"), "item" : "pqr", "quantity" : 345 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7601"), "item" : "stu", "quantity" : 56 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7602"), "item" : "vwx", "quantity" : 575 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7603"), "item" : "yzz", "quantity" : 398 }

現在,我們已經準備好並填充了我們的集合。關鍵是要考慮我們是否要從最近插入的文件到最近插入的文件中獲取最後 N 條記錄,反之亦然。

讓我們學習下面給出的每個場景。

從最近插入的文件到最近插入的文件中獲取最後 N 條記錄,反之亦然

在繼續之前,請檢視以下兩個術語以輕鬆理解它們:

  1. 最近到最近的排序

    這意味著後進先出(降序)。最後插入的文件將首先顯示。

  2. 從最近到最近的排序

    這意味著先進先出(升序)。最先插入的文件將首先顯示。

使用 cursor.sort() 方法從最近插入的文件到最近插入的文件中獲取最後 N 條記錄,反之亦然

示例程式碼(後進先出):

> db.stock.find().sort({_id:-1}).limit(3);

輸出:

{ "_id" : ObjectId("629ac651b7e637e64d8e7603"), "item" : "yzz", "quantity" : 398 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7602"), "item" : "vwx", "quantity" : 575 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7601"), "item" : "stu", "quantity" : 56 }

示例程式碼(先進先出):

> db.stock.find().sort({_id:1}).limit(3);

輸出:

{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }

在這裡,我們使用 sort() 方法將文件從最近到最近的插入順序(降序)排序。因此,在從資料庫中獲取任何文件(記錄)之前,我們將 sort() 方法應用於遊標。

sort() 方法的欄位值對為 {field: value},我們最多可以對 32 個鍵執行排序。使用 MongoDB 時,文件未按指定順序儲存在集合中。

這就是為什麼當我們對具有重複值的特定欄位執行排序時,具有這些值的文件可能會以任何順序返回。為了獲得一致的排序,我們必須至少包含一個包含唯一值的欄位。

確保這一點的最簡單方法是在 sort() 方法中使用 _id 欄位。

limit(N) 用於獲取指定數量的文件。如果我們有興趣獲取所有排序的文件,我們可以省略這個函式。

或者,我們也可以在沒有特定欄位的情況下使用如下查詢。

示例程式碼:

> db.stock.find().sort({$natural:1}).limit(3);

輸出:

{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }

如果 $natural 的值分別為 1-1,則它們的工作方式類似於先進先出和後進先出。如果我們有 MongoDB 4.4 或更高版本,我們可以使用它。

使用 $sort$limit (聚合) 階段從最近插入的文件到最近插入的文件中獲取最後 N 條記錄,反之亦然

示例程式碼(後進先出):

> db.stock.aggregate([
     { $sort : { _id : -1 } },
     { $limit : 4 }
]);

輸出:

{ "_id" : ObjectId("629ac651b7e637e64d8e7603"), "item" : "yzz", "quantity" : 398 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7602"), "item" : "vwx", "quantity" : 575 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7601"), "item" : "stu", "quantity" : 56 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7600"), "item" : "pqr", "quantity" : 345 }

示例程式碼(先進先出):

> db.stock.aggregate([
     { $sort : { _id : 1 } },
     { $limit : 4 }
]);

輸出:

{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fe"), "item" : "jkl", "quantity" : 345 }

$sort 聚合階段類似於 cursor.sort() 方法。它用於對所有文件進行排序,並將它們按排序順序返回到管道

它需要一個具有欄位名稱和相應排序順序的文件。請記住,1-1 用於升序和降序。

cursor.sort() 方法一樣,我們可以使用 $sort 聚合階段對最多 32 個鍵進行排序,並具有至少一個欄位(包含唯一值)以實現一致的排序順序。

如果我們需要對多個欄位進行排序,排序順序是從左到右評估的。而 $limit 採用一個數字,顯示需要在螢幕上列印多少個文件;此外,它具有 64 位整數限制。

結合使用 skip()count() 方法獲取 MongoDB 中的最後 N 條記錄

這種方法很吸引人,因為考慮到專案要求,我們不是對資料進行排序,而是從頭或尾獲取一段文件。

示例程式碼(獲取前 3 條記錄而不對文件進行排序):

> db.stock.find().limit(3);

輸出:

{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }

示例程式碼(獲取最後 3 條記錄而不對文件進行排序):

> db.stock.find().skip(db.stock.count() - 3)

輸出:

{ "_id" : ObjectId("629ac651b7e637e64d8e7601"), "item" : "stu", "quantity" : 56 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7602"), "item" : "vwx", "quantity" : 575 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7603"), "item" : "yzz", "quantity" : 398 }

在這個例子中,我們使用 db.stock.count() 來計算文件的總數,從中減去 3 並使用 skip() 方法跳過所有文件。

請記住,我們減去的文件數量沒有被跳過(在本例中為 3)。我們將得到這 3 個檔案。

作者: Mehvish Ashiq
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook