本指南中的代码示例来自驾驶员源代码Github存储库中的 QuickTour.java 文件。
注意
有关如何安装Java Reactive Streams驾驶员的说明,请参阅安装指南。
重要
本指南使用 Subscriber
实现,如快速入门入门中所述。
先决条件
您必须设置以下组件才能运行本指南中的代码示例:
在 MongoDB 默认端口 (
27017
) 上运行的 MongoDB 服务器项目中安装的驱动程序依赖项
以下 import 语句:
import com.mongodb.bulk.BulkWriteResult; import com.mongodb.client.model.BulkWriteOptions; import com.mongodb.client.model.DeleteOneModel; import com.mongodb.client.model.InsertOneModel; import com.mongodb.client.model.ReplaceOneModel; import com.mongodb.client.model.UpdateOneModel; import com.mongodb.client.model.WriteModel; import com.mongodb.client.result.InsertOneResult; import com.mongodb.client.result.InsertManyResult; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoCollection; import com.mongodb.reactivestreams.client.MongoDatabase; import org.bson.Document; import java.util.ArrayList; import java.util.List; import static com.mongodb.client.model.Accumulators.*; import static com.mongodb.client.model.Aggregates.*; import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Projections.*; import static com.mongodb.client.model.Sorts.*; import static com.mongodb.client.model.Updates.*; import static java.util.Arrays.asList; import static java.util.Collections.singletonList;
建立连接
使用MongoClients.create()
方法连接到正在运行的 MongoDB 部署。
MongoClient
实例表示数据库的连接池。 即使使用并发操作线程,也只需要一个MongoClient
实例。
重要
通常,您仅为给定 MongoDB 部署(例如独立部署、副本集或分片集群)仅创建一个MongoClient
实例,并在整个应用程序中使用该客户端。 但是,如果您确实创建了多个实例,请记住以下几点:
所有资源使用限制(例如最大连接数)均适用于每个
MongoClient
实例。要丢弃实例,请调用
MongoClient.close()
方法来清理资源。
连接到单个 MongoDB 部署
以下示例展示了连接到单个 MongoDB 部署的几种方法。
您可以通过以下方式连接到单个MongoDB 部署:
实例化一个不带任何参数的
MongoClient
对象,以连接到在本地主机上运行的 MongoDB 服务器的端口27017
:MongoClient mongoClient = MongoClients.create(); 显式指定
hostname
以连接到在指定主机的端口27017
上运行的 MongoDB 实例:MongoClient mongoClient = MongoClients.create( MongoClientSettings.builder() .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new ServerAddress("hostOne")))) .build()); 显式指定
hostname
和port
:MongoClient mongoClient = MongoClients.create( MongoClientSettings.builder() .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new ServerAddress("hostOne", 27018)))) .build()); 指定
ConnectionString
:MongoClient mongoClient = MongoClients.create("mongodb://hostOne:27017");
访问数据库
将MongoClient
实例连接到 MongoDB 部署后,使用MongoClient.getDatabase()
方法访问数据库。
为getDatabase()
方法指定数据库的名称。 如果数据库不存在,MongoDB 会在您首次为该数据库存储数据时创建该数据库。
以下示例将访问mydb
数据库:
MongoDatabase database = mongoClient.getDatabase("mydb");
MongoDatabase
实例不可变。
访问集合
获得MongoDatabase
实例后,使用getCollection()`
方法访问权限集合。
为getCollection()
方法指定集合的名称。 如果集合不存在, MongoDB会在您首次存储该集合。
示例,以下声明使用数据库实例访问mydb
数据库中名为test
的集合:
MongoCollection<Document> collection = database.getCollection("test");
MongoCollection
实例不可变。
创建文档
要使用驾驶员创建文档,请使用Document
类。
例如,考虑以下JSON document :
{ "name" : "MongoDB", "type" : "database", "count" : 1, "versions": [ "v3.2", "v3.0", "v2.6" ], "info" : { x : 203, y : 102 } }
要使用驱动程序创建文档,请使用字段和值实例化Document
对象,并使用其append()
方法将其他字段和值包含到文档对象中。 该值可以是另一个Document
对象,用于指定嵌入式文档:
Document doc = new Document("name", "MongoDB") .append("type", "database") .append("count", 1) .append("versions", Arrays.asList("v3.2", "v3.0", "v2.6")) .append("info", new Document("x", 203).append("y", 102));
注意
数组的 BSON 类型对应于 Java 类型java.util.List
。 有关BSON types和Java中相应类型的列表,请参阅 Document
映射。
插入文档
获得MongoCollection
对象后,您可以将文档插入到集合中。
插入一个文档
要将单个文档插入集合,可以使用insertOne()
方法。
var subscriber = new OperationSubscriber<InsertOneResult>(); collection.insertOne(doc).subscribe(subscriber); // Wait for the insertOne operation to complete subscriber.await();
注意
如果文档中没有指定顶级_id
字段,MongoDB 会自动生成一个值并将该字段添加到插入的文档中。
重要
在 API 中,所有返回Publisher
实例的方法都是冷流,这意味着在它们被订阅之前不会发生任何事情。
例如,以下示例不执行任何操作:
Publisher<InsertOneResult> publisher = collection.insertOne(doc);
该操作仅在订阅Publisher
并请求数据时发生。
publisher.subscribe(new Subscriber<InsertOneResult>() { public void onSubscribe(final Subscription s) { s.request(1); // <--- Data requested and the insertion will now occur } public void onNext(final InsertOneResult result) { System.out.println("Inserted: " + result); } public void onError(final Throwable t) { System.out.println("Failed"); } public void onComplete() { System.out.println("Completed"); } });
插入文档后,系统会调用onNext()
方法并打印Inserted:
,然后打印结果。 最后, onComplete()
方法会打印Completed
。 如果由于任何原因出现错误, onError()
方法将打印Failed
。
插入多个文档
要插入多个文档,可以使用集合的insertMany()
方法,该方法获取要插入的文档列表。
以下示例按以下形式添加多个文档:
{ "i" : value }
在循环中创建文档并将它们添加到documents
列表中:
List<Document> documents = new ArrayList<Document>(); for (int i = 0; i < 100; i++) { documents.add(new Document("i", i)); }
要将这些文档插入到集合中,请将文档列表传递给insertMany()
方法:
var subscriber = new OperationSubscriber<InsertManyResult>(); collection.insertMany(documents).subscribe(subscriber); // Wait for the insertMany operation to complete subscriber.await();
上一个示例会在Publisher
完成时阻塞。 这可确保在运行下一个操作之前数据已存储在数据库中。
对集合中的文档进行计数
要计算集合中的文档数量,可以使用集合的countDocuments()
方法。 以下代码应打印101
,描述使用insertMany()
100文档以及使用insertOne()
1插入的 。
collection.count() .subscribe(new PrintSubscriber<Long>("total # of documents: %s"));
查询集合
要查询集合,可以使用集合的find()
方法。 您可以不带任何参数调用该方法来查询集合中的所有文档,也可以传递过滤来查询与过滤条件匹配的文档。
查找集合中的第一个文档
要返回集合中的第一个文档,请使用不带任何参数的find()
方法,并链接first()
方法。
提示
find().first()
构造对于只应匹配单个文档的查询或仅对第一个匹配的文档感兴趣时非常有用。
以下示例打印在集合中找到的第一个文档:
collection.find().first().subscribe(new PrintDocumentSubscriber());
该示例应打印以下文档:
{ "_id" : { "$oid" : "551582c558c7b4fbacf16735" }, "name" : "MongoDB", "type" : "database", "count" : 1, "info" : { "x" : 203, "y" : 102 } }
注意
_id
元素已由MongoDB自动添加到您的文档中,您的值将与显示的不同。 MongoDB保留以_
和$
开头的字段名称供内部使用。
查找集合中的所有文档
要检索集合中的所有文档,请使用find()
方法。 find()
方法返回一个FindPublisher
实例,该实例为链接或控制查找操作提供流畅的接口。 以下代码检索并打印集合中的所有文档:
collection.find().subscribe(new PrintDocumentSubscriber());
指定查询筛选器
要查询匹配特定条件的文档,请将过滤对象传递给find()
方法。 为了便于创建过滤对象,驾驶员提供了Filters
辅助方法。
获取与筛选器匹配的单个文档
要查找字段i
的值为71
的第一个文档,请传递eq()
过滤定义以指定相等条件:
collection.find(eq("i", 71)).first().subscribe(new PrintDocumentSubscriber());
该示例打印一个文档:
{ "_id" : { "$oid" : "5515836e58c7b4fbc756320b" }, "i" : 71 }
获取与筛选器匹配的所有文档
以下示例返回并打印i
值大于50
的所有文档:
collection.find(gt("i", 50)).subscribe(new PrintDocumentSubscriber());
要为范围指定过滤器,例如50 < i <= 100
,可以使用and()
助手:
collection.find(and(gt("i", 50), lte("i", 100))) .subscribe(new PrintDocumentSubscriber());
Update Documents
要更新集合中的文档,可以使用集合的updateOne()
和updateMany()
方法。
将以下参数传递给这些方法:
筛选对象以确定要更新的一个或多个文档。 为了便于创建过滤对象,驾驶员提供了
Filters
辅助方法。 要指定空过滤并匹配集合中的所有文档,请使用空Document
对象。
更新方法返回UpdateResult
类型,其中提供有关操作的信息,包括更新修改的文档数量。
更新单份文档
要更新单个文档,请使用updateOne()
方法。
以下示例更新i
为10
的第一个文档,并将i
的值设置为110
:
collection.updateOne(eq("i", 10), set("i", 110)) .subscribe(new PrintSubscriber<UpdateResult>("Update Result: %s"));
更新多个文档
要更新与查询筛选器匹配的所有文档,请使用updateMany()
方法。
以下示例在 值小于i
100
的所有文档中将 的值递增i
100
:
UpdateResult updateResult = collection.updateMany(lt("i", 100), inc("i", 100)) .subscribe(new PrintSubscriber<UpdateResult>("Update Result: %s"));
Delete Documents
要从集合中删除文档,可以使用集合的deleteOne()
和deleteMany()
方法。
传递过滤对象以确定要删除的一个或多个文档。 为了便于创建过滤对象,驾驶员提供了Filters
辅助方法。 要指定空过滤并匹配集合中的所有文档,请使用空Document
对象。
删除方法返回DeleteResult
,其中提供有关操作的信息,包括删除的文档数。
删除与筛选器匹配的单个文档
要删除与筛选器匹配的单个文档,请使用deleteOne()
方法。
以下示例删除了i
的值等于110
的第一个文档:
collection.deleteOne(eq("i", 110)) .subscribe(new PrintSubscriber<DeleteResult>("Delete Result: %s"));
删除与筛选器匹配的所有文档
要删除与过滤匹配的所有文档,请使用deleteMany()
方法。
以下示例删除i
值大于或等于100
的所有文档:
DeleteResult deleteResult = collection.deleteMany(gte("i", 100)) .subscribe(new PrintSubscriber<DeleteResult>("Delete Result: %s"));
createIndexes
要在一个或多个字段上创建索引,请将索引规范文档传递给createIndex()
方法。 索引键规范文档包含要索引的字段以及每个字段的索引类型,由以下文档建模:
new Document(<field1>, <type1>).append(<field2>, <type2>) ...
要创建升序索引类型,请为 指定1
<type>
。要创建降序索引类型,请为 指定-1
<type>
。
以下示例在i
字段上创建一个升序索引:
collection.createIndex(new Document("i", 1)) .subscribe(new PrintSubscriber<String>("Create Index Result: %s"));
要查看其他索引类型的列表,请参阅创建索引指南。
更多信息
有关演示如何将 MongoDB 与 POJO 结合使用的其他教程,请参阅快速入门(POJO 示例)指南。
要查找其他教程,请参阅教程部分。