Docs 菜单
Docs 主页
/ / /
Java Reactive Streams 驱动程序
/

读取操作

在此页面上

  • 先决条件
  • 连接到 MongoDB 部署
  • 查询集合
  • 查询过滤器
  • 清空筛选器
  • 筛选器助手
  • FindPublisher
  • 投影
  • 排序
  • 使用投影排序
  • 解释
  • 读取偏好
  • 读关注 (read concern)

读取操作从集合中检索文档或文档信息。 您可以指定筛选器,仅检索符合筛选条件的文档。

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

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

以下代码连接到在端口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 文档。

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() 方法的示例,请参阅文本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());

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");
  • MongoDatabase中,使用withReadConcern()方法:

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

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

后退

createIndexes