MongoDB中使用文档ID进行查询操作概述
在这个教程中,我们将探讨如何在MongoDB中使用文档ID执行查询操作。MongoDB提供了一个*find*
操作符,用于从集合中检索文档。
首先,我们将在MongoDB shell查询中查看使用文档ID查询文档的方法,然后使用Java驱动程序代码。
2. 文档ID是什么?
与任何其他数据库管理系统一样,MongoDB需要为存储在集合中的每个文档提供一个唯一的标识符,作为集合的主键。
在MongoDB中,ID由12字节组成:
- 4字节的时间戳,表示自Unix纪元以来的秒数
- 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")
});
此查询返回\_id
等于ObjectId("62d01d17cdd1b7c8a5f945b9")
的vehicle
集合文档:
{ "_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
运算符中查询到的所有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" }
同样,可以使用所有查询运算符作为find()
方法的过滤器,使用要查询的ID。
另外,值得注意的是,在使用\_id
字段查询文档时,文档ID的字符串值应指定为ObjectId()
,而不是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");
在这种情况下,我们连接到运行在本地主机默认端口27017上的MongoDB。
首先,编写代码使用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());
}
在这里,我们向find()
方法传递一个Bson
过滤器,其中包含\_id
字段以进行查询。上述代码将返回\_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());
}
上述查询返回查询到的所有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的文档。
6. 总结
在这篇文章中,我们学习了如何在MongoDB中使用文档ID查询文档。首先,我们在MongoDB shell查询中探讨了这些用例,然后讨论了相应的Java驱动程序代码。
所有这些示例和代码片段的实现可在GitHub上找到。