读取操作
读取操作从集合中检索文档或有关文档的信息。您可以指定一个过滤器来检索仅匹配过滤器条件的文档。
先决条件
您必须设置以下组件以运行本指南中的代码示例
A
test.restaurants集合,由文档组成,这些文档来自位于文档资产 GitHub 中的restaurants.json文件文档.以下导入语句
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 实现,这些实现已在 Quick Start Primer 中描述中.
连接到 MongoDB 部署
首先,连接到 MongoDB 部署,然后声明并定义 MongoDatabase 和 MongoCollection 实例。
以下代码连接到在 localhost 上运行的独立 MongoDB 部署,端口号为 27017。然后,它定义 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且小于5categories字段等于"Bakery",或者如果categories是数组字段,包含字符串"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());
findPublisher
find()方法返回FindPublisher接口的实例。该接口提供各种方法,可以将这些方法链接到find()方法来修改查询的输出或行为,例如sort()或projection(),以及通过subscribe()方法迭代结果。
Projections
默认情况下,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()方法的示例,请参阅文本搜索教程。
排序
要排序文档,请将排序规范文档传递给FindPublisher.sort()方法。驱动程序提供了Sorts辅助方法,以简化排序规范文档的创建。
collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery"))) .sort(Sorts.ascending("name")) .subscribe(new PrintDocumentSubscriber());
使用投影排序
FindPublisher方法本身返回FindPublisher对象,因此您可以向find()方法添加多个FindPublisher方法。
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());
读取关注
对于副本集或分片集群的读取操作,应用程序可以在以下级别配置读取关注
在以下方式中的
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");
使用
withReadConcern()方法在MongoDatabaseMongoDatabase database = mongoClient.getDatabase("test") .withReadConcern(ReadConcern.MAJORITY); 使用
withReadConcern()方法在MongoCollectionMongoCollection<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);