文档菜单
文档首页
/ / /
Java 反应式流驱动程序
/

读取操作

本页内容

  • 先决条件
  • 连接到 MongoDB 部署
  • 查询集合
  • 查询过滤器
  • 空过滤器
  • 过滤器助手
  • FindPublisher
  • 投影
  • 排序
  • 带有投影的排序
  • 解释
  • 读取偏好
  • 读取关注点

读取操作从集合中检索文档或有关文档的信息。您可以指定一个过滤器来检索仅匹配过滤器条件的文档。

您必须设置以下组件以运行本指南中的代码示例

  • Atest.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 部署,然后声明并定义 MongoDatabaseMongoCollection 实例。

以下代码连接到在 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 且小于 5

  • categories 字段等于 "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());

要查看查询筛选运算符列表,请参阅服务器手册中的查询和投影运算符。要查看过滤器API文档过滤器助手的列表。

find()方法返回FindPublisher接口的实例。该接口提供各种方法,可以将这些方法链接到find()方法来修改查询的输出或行为,例如sort()projection(),以及通过subscribe()方法迭代结果。

默认情况下,MongoDB中的查询返回匹配文档中的所有字段。为了指定匹配文档中返回的字段,您可以指定一个投影文档。

此查询操作示例包含一个投影Document,指定匹配的文档仅包含namestarscategories字段。

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());

MongoDatabaseMongoCollection 实例是不可变的。对现有的 MongoDatabaseMongoCollection 实例调用 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() 方法在 MongoDatabase

    MongoDatabase database = mongoClient.getDatabase("test")
    .withReadConcern(ReadConcern.MAJORITY);
  • 使用 withReadConcern() 方法在 MongoCollection

    MongoCollection<Document> collection = database.getCollection("restaurants")
    .withReadConcern(ReadConcern.MAJORITY);

MongoDatabaseMongoCollection 实例是不可变的。对现有的 MongoDatabaseMongoCollection 实例调用 withReadConcern() 返回一个新的实例,并且不会影响调用该方法时的实例。

以下示例中,collWithReadConcern 实例具有 AVAILABLE 读取关注,而 collection 的读取关注不受影响

MongoCollection<Document> collWithReadConcern = collection.withReadConcern(ReadConcern.AVAILABLE);

您可以将 MongoClientSettingsMongoDatabaseMongoCollection 实例构建为包含读取关注、读取偏好和写入关注组合。

例如,以下代码在集合级别设置了所有三个

collection = database.getCollection("restaurants")
.withReadPreference(ReadPreference.primary())
.withReadConcern(ReadConcern.MAJORITY)
.withWriteConcern(WriteConcern.MAJORITY);

返回

创建索引