读取操作
读取操作从集合中检索文档或文档信息。 您可以指定筛选器,仅检索符合筛选条件的文档。
先决条件
您必须设置以下组件才能运行本指南中的代码示例:
一个
test.restaurants
restaurants.json
集合,其中填充了来自 文档资产Github 中的 文件的文档。以下 import 语句:
import com.mongodb.*; import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoCollection; import com.mongodb.reactivestreams.client.MongoDatabase; import com.mongodb.client.model.Projections; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Sorts; import java.util.Arrays; import org.bson.Document; import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Projections.*;
重要
本指南使用Subscriber
实现,如快速入门入门知识中所述。
连接到 MongoDB 部署
首先,连接到 MongoDB 部署,然后声明并定义MongoDatabase
和MongoCollection
实例。
以下代码连接到在端口27017
上的localhost
上运行的独立 MongoDB 部署。 然后,定义database
变量以引用test
数据库,并collection
变量以引用restaurants
集合:
MongoClient mongoClient = MongoClients.create(); MongoDatabase database = mongoClient.getDatabase("test"); MongoCollection<Document> collection = database.getCollection("restaurants");
要了解有关连接到 MongoDB 部署的更多信息,请参阅连接到 MongoDB教程。
查询集合
要查询集合,可以使用集合的find()
方法。
您可以不带任何参数调用该方法来查询集合中的所有文档:
collection.find().subscribe(new PrintDocumentSubscriber());
或者,您可以传递筛选器来查询与筛选条件匹配的文档:
collection.find(eq("name", "456 Cookies Shop")) .subscribe(new PrintDocumentSubscriber());
查询过滤器
要查询匹配特定条件的文档,请将筛选器文档传递给find()
方法。
清空筛选器
要指定空筛选器并匹配集合中的所有文档,请使用空Document
对象:
collection.find(new Document()).subscribe(new PrintDocumentSubscriber());
提示
使用find()
方法时,您还可以在不传递任何筛选器对象的情况下调用该方法来匹配集合中的所有文档。
collection.find().subscribe(new PrintDocumentSubscriber());
筛选器助手
为了便于创建筛选器文档,驱动程序提供了Filters
类,该类提供筛选条件辅助方法。
此示例查找操作包含一个筛选器Document
实例,该实例指定以下条件:
stars
字段值大于或等于2
且小于5
categories
字段等于"Bakery"
,或者如果categories
是数组字段,则包含string"Bakery"
作为元素
collection.find( new Document("stars", new Document("$gte", 2) .append("$lt", 5)) .append("categories", "Bakery")).subscribe(new PrintDocumentSubscriber());
以下示例使用Filters
辅助方法指定相同的筛选条件:
collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery"))) .subscribe(new PrintDocumentSubscriber());
要查看查询筛选操作符的列表,请参阅 MongoDB Server手册中的 查询和投影操作符 。要查看Filters
助手列表,请参阅 筛选器 API 文档。
FindPublisher
find()
方法返回FindPublisher
接口的实例。 该接口提供了各种方法,您可以链接到find()
方法,以修改查询的输出或行为,例如sort()
或projection()
,以及通过subscribe()
方法迭代结果。
投影
默认情况下,MongoDB 中的查询返回匹配文档中的所有字段。 要指定要在匹配文档中返回的字段,可以指定投影文档。
此查找操作示例包含一个投影Document
,该投影指定匹配文档仅包含name
、 stars
和categories
字段:
collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery"))) .projection(new Document("name", 1) .append("stars", 1) .append("categories",1) .append("_id", 0)) .subscribe(new PrintDocumentSubscriber());
为了便于创建投影文档,驱动程序提供了Projections
类。
collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery"))) .projection(fields(include("name", "stars", "categories"), excludeId())) .subscribe(new PrintDocumentSubscriber());
在投影文档中,您还可以使用投影操作符指定投影表达式。
要查看使用 Projections.metaTextScore()
方法的示例,请参阅文本Atlas Search教程。
排序
要对文档进行排序,请将排序规范文档传递给FindPublisher.sort()
方法。 驱动程序提供了Sorts
辅助方法来促进排序规范文档的创建。
collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery"))) .sort(Sorts.ascending("name")) .subscribe(new PrintDocumentSubscriber());
使用投影排序
FindPublisher
方法本身返回FindPublisher
对象,因此,您可以将多个FindPublisher
方法附加到find()
方法:
collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery"))) .sort(Sorts.ascending("name")) .projection(fields(include("name", "stars", "categories"), excludeId())) .subscribe(new PrintDocumentSubscriber());
解释
要解释查找操作,请调用FindPublisher.explain()
方法:
collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery"))) .explain() .subscribe(new PrintDocumentSubscriber());
读取偏好
对于副本集或分片集群上的读取操作,您可以在以下级别配置读取偏好:
在
MongoClient
中通过以下方式:通过创建
MongoClientSettings
实例:MongoClient mongoClient = MongoClients.create(MongoClientSettings.builder() .applyConnectionString(new ConnectionString("mongodb://host1,host2")) .readPreference(ReadPreference.secondary()) .build()); 通过创建
ConnectionString
实例:MongoClient mongoClient = MongoClients.create("mongodb://host1:27017,host2:27017/?readPreference=secondary");
在
MongoDatabase
中,使用withReadPreference()
方法:MongoDatabase database = mongoClient.getDatabase("test") .withReadPreference(ReadPreference.secondary()); 在
MongoCollection
中,使用withReadPreference()
方法:MongoCollection<Document> collection = database.getCollection("restaurants") .withReadPreference(ReadPreference.secondary());
MongoDatabase
和MongoCollection
实例是不可变的。 在现有MongoDatabase
或MongoCollection
实例上调用withReadPreference()
会返回一个新实例,并且不会影响调用该方法的实例。
在以下示例中, collectionWithReadPref
实例的读取偏好为primaryPreferred
,而collection
的读取偏好不受影响:
MongoCollection<Document> collectionWithReadPref = collection.withReadPreference(ReadPreference.primaryPreferred());
读关注 (read concern)
对于副本集或分片集群上的读取操作,应用程序可以在以下级别配置读关注:
在
MongoClient
中通过以下方式:通过创建
MongoClientSettings
实例:MongoClient mongoClient = MongoClients.create(MongoClientSettings.builder() .applyConnectionString(new ConnectionString("mongodb://host1,host2")) .readConcern(ReadConcern.MAJORITY) .build()); 通过创建
ConnectionString
实例:MongoClient mongoClient = MongoClients.create("mongodb://host1:27017,host2:27017/?readConcernLevel=majority");
在
MongoDatabase
中,使用withReadConcern()
方法:MongoDatabase database = mongoClient.getDatabase("test") .withReadConcern(ReadConcern.MAJORITY); 在
MongoCollection
中,使用withReadConcern()
方法:MongoCollection<Document> collection = database.getCollection("restaurants") .withReadConcern(ReadConcern.MAJORITY);
MongoDatabase
和MongoCollection
实例是不可变的。 在现有MongoDatabase
或MongoCollection
实例上调用withReadConcern()
会返回一个新实例,并且不会影响调用该方法的实例。
在以下示例中, collWithReadConcern
实例有一个AVAILABLE
读关注,而collection
的读关注不受影响:
MongoCollection<Document> collWithReadConcern = collection.withReadConcern(ReadConcern.AVAILABLE);
您可以构建MongoClientSettings
、 MongoDatabase
或MongoCollection
实例以包含读关注、读取偏好和写关注的组合。
例如,以下代码在集合级别设置所有三个:
collection = database.getCollection("restaurants") .withReadPreference(ReadPreference.primary()) .withReadConcern(ReadConcern.MAJORITY) .withWriteConcern(WriteConcern.MAJORITY);