在 MongoDB 中使用 Document ID 查詢文檔
一、概述
在本教程中,我們將研究在 MongoDB 中使用 Document ID 執行查詢操作。 MongoDB 提供了一個find操作符來從集合中查詢文檔。
在本教程中,我們將首先查看在 MongoDB Shell 查詢中使用 Document ID 查詢文檔,然後使用 Java 驅動程序代碼。
2. MongoDB Document 的 Document ID 是什麼?
就像任何其他數據庫管理系統一樣,MongoDB 要求存儲在集合中的每個文檔都有一個唯一標識符。此唯一標識符充當集合的主鍵。
在 MongoDB 中,ID 由 12 個字節組成:
- 一個 4 字節的時間戳,表示自 Unix 紀元以來 ID 的創建時間,以秒為單位
 - 機器和進程唯一的 5 字節隨機生成值
 - 一個 3 字節遞增計數器
 
在 MongoDB 中, ID 存儲在名為_id的字段中,由客戶端生成。因此,應在將文檔發送到數據庫之前生成 ID。在客戶端,我們可以使用驅動程序生成的 ID 或生成自定義 ID。
唯一標識符存儲在ObjectId類中。這個類提供了方便的方法來獲取存儲在 ID 中的數據,而無需實際解析它。如果在插入文檔時未指定_id ,MongoDB 將添加_id字段並為文檔分配唯一的ObjectId 。
3. 數據庫初始化
首先,讓我們建立一個新的數據庫baeldung和一個樣本集合, vehicle :
use baeldung;
 db.createCollection("vehicle");
此外,讓我們使用insertMany方法將一些文檔添加到集合中:
db.vehicle.insertMany([
 {
 "companyName":"Skoda",
 "modelName":"Octavia",
 "launchYear":2016,
 "type":"Sports",
 "registeredNo":"SKO 1134"
 },
 {
 "companyName":"BMW",
 "modelName":"X5",
 "launchYear":2020,
 "type":"SUV",
 "registeredNo":"BMW 3325"
 },
 {
 "companyName":"Mercedes",
 "modelName":"Maybach",
 "launchYear":2021,
 "type":"Luxury",
 "registeredNo":"MER 9754"
 }]);
如果插入成功,上面的命令將打印一個類似於下圖的 JSON:
{
 "acknowledged" : true,
 "insertedIds" : [
 ObjectId("62d01d17cdd1b7c8a5f945b9"),
 ObjectId("62d01d17cdd1b7c8a5f945ba"),
 ObjectId("62d01d17cdd1b7c8a5f945bb")
 ]
 }
我們已成功設置數據庫和集合。我們將在所有示例中使用這個數據庫和集合。
4. 使用 MongoDB Shell
我們將使用db.collection.find(query, projection)方法從 MongoDB 中查詢文檔。
首先,讓我們編寫一個返回所有vehicle集合文檔的查詢:
db.vehicle.find({});
上面的查詢返回所有文檔:
{ "_id" : ObjectId("62d01d17cdd1b7c8a5f945b9"), "companyName" : "Skoda",
 "modelName" : "Octavia", "launchYear" : 2016, "type" : "Sports", "registeredNo" : "SKO 1134" }
 { "_id" : ObjectId("62d01d17cdd1b7c8a5f945ba"), "companyName" : "BMW",
 "modelName" : "X5", "launchYear" : 2020, "type" : "SUV", "registeredNo" : "BMW 3325" }
 { "_id" : ObjectId("62d01d17cdd1b7c8a5f945bb"), "companyName" : "Mercedes",
 "modelName" : "Maybach", "launchYear" : 2021, "type" : "Luxury", "registeredNo" : "MER 9754" }
此外,讓我們編寫一個查詢來使用上面結果中返回的 ID 獲取vehicle集合文檔:
db.vehicle.find(
 {
 "_id": ObjectId("62d01d17cdd1b7c8a5f945b9")
 });
上述查詢返回vehicle集合文檔, _id等於ObjectId(“62d01d17cdd1b7c8a5f945b9”) :
{ "_id" : ObjectId("62d01d17cdd1b7c8a5f945b9"), "companyName" : "Skoda",
 "modelName" : "Octavia", "launchYear" : 2016, "type" : "Sports", "registeredNo" : "SKO 1134" }
此外,我們可以使用帶有in查詢運算符的 ID 檢索多個vehicle收集文檔:
db.vehicle.find(
 {
 "_id": {
 $in: [
 ObjectId("62d01d17cdd1b7c8a5f945b9"),
 ObjectId("62d01d17cdd1b7c8a5f945ba"),
 ObjectId("62d01d17cdd1b7c8a5f945bb")
 ]
 }
 });
上述查詢返回in操作符中查詢到的 ID 的所有vehicle收集文檔:
{ "_id" : ObjectId("62d01d17cdd1b7c8a5f945b9"), "companyName" : "Skoda",
 "modelName" : "Octavia", "launchYear" : 2016, "type" : "Sports", "registeredNo" : "SKO 1134" }
 { "_id" : ObjectId("62d01d17cdd1b7c8a5f945ba"), "companyName" : "BMW",
 "modelName" : "X5", "launchYear" : 2020, "type" : "SUV", "registeredNo" : "BMW 3325" }
 { "_id" : ObjectId("62d01d17cdd1b7c8a5f945bb"), "companyName" : "Mercedes",
 "modelName" : "Maybach", "launchYear" : 2021, "type" : "Luxury", "registeredNo" : "MER 9754" }
同樣,任何查詢運算符都可以用作帶有要查詢的 ID 的find()方法的過濾器。
此外,需要注意的是,在使用_id字段查詢文檔時,文檔 ID 字符串值應指定為ObjectId()而不是String 。
讓我們嘗試使用 ID 作為String值來查詢現有文檔:
db.vehicle.find(
 {
 "_id": "62d01d17cdd1b7c8a5f945b9"
 });
不幸的是,上述查詢不會返回任何文檔,因為不存在任何 ID 為String值為62d01d17cdd1b7c8a5f945b9的文檔。
5. 使用 Java 驅動程序
到目前為止,我們已經學習瞭如何在 MongoDB Shell 中使用 ID 來查詢文檔。現在讓我們使用 MongoDB Java 驅動程序實現相同的功能。
在執行更新操作之前,我們先連接到baeldung數據庫中的vehicle集合:
MongoClient mongoClient = new MongoClient("localhost", 27017);
 MongoDatabase database = mongoClient.getDatabase("baeldung");
 MongoCollection<Document> collection = database.getCollection("vehicle");
在這裡,在這種情況下,我們連接到 MongoDB,它在 localhost 的默認端口 27017 上運行。
首先,讓我們編寫使用 ID 查詢文檔的代碼:
Bson filter = Filters.eq("_id", new ObjectId("62d01d17cdd1b7c8a5f945b9"));
 FindIterable<Document> documents = collection.find(filter);
 MongoCursor<Document> cursor = documents.iterator();
 while (cursor.hasNext()) {
 System.out.println(cursor.next());
 }
在這裡,我們將Bson過濾器作為參數傳遞給帶有_id字段的find()方法進行查詢。上面的代碼片段將返回_id等於ObjectId(“62d01d17cdd1b7c8a5f945b9”)的vehicle收集文檔。
此外,讓我們編寫一個片段來查詢具有多個 ID 的文檔:
Bson filter = Filters.in("_id", new ObjectId("62d01d17cdd1b7c8a5f945b9"),
 new ObjectId("62d01d17cdd1b7c8a5f945ba"));
 FindIterable<Document> documents = collection.find(filter);
 MongoCursor<Document> cursor = documents.iterator();
 while (cursor.hasNext()) {
 System.out.println(cursor.next());
 }
上述查詢返回查詢到的 ID 的所有vehicle收集文檔。
最後,讓我們嘗試使用駕駛員生成的 ID 查詢vehicle集合:
Bson filter = Filters.eq("_id", new ObjectId());
 FindIterable<Document> documents = collection.find(filter);
 MongoCursor<Document> cursor = documents.iterator();
 while (cursor.hasNext()) {
 System.out.println(cursor.next());
 }
上述查詢不會返回任何文檔,因為具有新生成 ID 的文檔不會存在於vehicle集合中。
六,結論
在本文中,我們學習了在 MongoDB 中使用 Document ID 查詢文檔。首先,我們在 MongoDB Shell 查詢中研究了這些用例,然後我們討論了相應的 Java 驅動程序代碼。
所有這些示例和代碼片段的實現都可以在 GitHub 上找到。