Docs Menu
Docs Home
/ / /
Scala
/

Read Operations

On this page

  • Prerequisites
  • Connect to a MongoDB Deployment
  • Query a Collection
  • Query Filters
  • Empty Filter
  • Filters Helper
  • FindObservable
  • Projections
  • Sorts
  • Sort with Projections
  • Explain
  • Read Preference
  • Read Concern

Read operations retrieve documents or information about documents from a collection. You can specify a filter to retrieve only those documents that match the filter condition.

You must set up the following components to run the code examples in this guide:

  • A test.restaurants collection populated with documents from the restaurants.json file in the documentation assets GitHub.

  • The following import statements:

import org.mongodb.scala._
import org.mongodb.scala.model.Filters._
import org.mongodb.scala.model.Projections._
import org.mongodb.scala.model.Sorts._

Note

This guide uses the Observable implicits as covered in the Quick Start Primer.

First, connect to a MongoDB deployment, then declare and define MongoDatabase and MongoCollection instances.

The following code connects to a standalone MongoDB deployment running on localhost on port 27017. Then, it defines the database variable to refer to the test database and the collection variable to refer to the restaurants collection:

val mongoClient: MongoClient = MongoClient()
val database: MongoDatabase = mongoClient.getDatabase("test")
val collection: MongoCollection[Document] = database.getCollection("restaurants")

To learn more about connecting to MongoDB deployments, see the Connect to MongoDB tutorial.

To query the collection, you can use the collection's find() method.

You can call the method without any arguments to query all documents in a collection:

collection.find().printResults()

Or, you can pass a filter to query for documents that match the filter criteria:

collection.find(equal("name", "456 Cookies Shop"))
.printResults()

To query for documents that match certain conditions, pass a filter document to the find() method.

To specify an empty filter and match all documents in a collection, use an empty Document object:

collection.find(Document()).printResults()

Tip

When using the find() method, you can also call the method without passing any filter object to match all documents in a collection.

collection.find().printResults()

To facilitate the creation of filter documents, the driver provides the Filters class that provides filter condition helper methods. To learn about these methods, see the Filters guide.

This example find operation includes a filter Document instance which specifies the following conditions:

  • stars field value is greater than or equal to 2 and less than 5

  • categories field equals "Bakery", or if categories is an array field, contains the string "Bakery" as an element

collection.find(
Document("stars" -> Document("$gte" -> 2, "$lt"-> 5, "categories" -> "Bakery")))
.printResults()

The following example specifies the same filter condition using the Filters helper methods:

collection.find(and(gte("stars", 2), lt("stars", 5), equal("categories", "Bakery")))
.printResults()

To view a list of query filter operators, see Query and Projection Operators in the Server manual. To view a list of Filters helpers, see the Filters API documentation.

The find() method returns an instance of the FindObservable class. The class provides various methods that you can chain to the find() method to modify the output or behavior of the query, such as sort() or projection(), as well as for iterating the results via the subscribe() method.

By default, queries in MongoDB return all fields in matching documents. To specify the fields to return in the matching documents, you can specify a projection document.

This find operation example includes a projection Document which specifies that the matching documents include only the name, stars, and the categories fields:

collection.find(and(gte("stars", 2), lt("stars", 5), equal("categories", "Bakery")))
.projection(Document("name" -> 1, "stars" -> 1, "categories" -> 1, "_id" -> 0))
.printResults()

To facilitate the creation of projection documents, the driver provides the Projections class helper methods. To learn more about these methods, see the Projections guide.

collection.find(and(gte("stars", 2), lt("stars", 5), equal("categories", "Bakery")))
.projection(fields(include("name", "stars", "categories"), excludeId()))
.printResults()

In the projection document, you can also specify a projection expression by using a projection operator.

To view an example that uses the Projections.metaTextScore() method, see the Text Search tutorial.

To sort documents, pass a sort specification document to the FindObservable.sort() method. The driver provides Sorts helper methods to facilitate the creation of the sort specification document. To learn how to build sort critera by using builders, see the Sorts guide.

collection.find(and(gte("stars", 2), lt("stars", 5), equal("categories", "Bakery")))
.sort(ascending("name"))
.printResults()

The FindObservable methods themselves return FindObservable objects, and as such, you can append multiple FindObservable methods to the find() method:

collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery")))
.explain()
.printResults()

To explain a find operation, call the FindObservable.explain() method:

collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery")))
.explain()
.printResults()

For read operations on replica sets or sharded clusters, you can configure the read preference at the following levels:

  • In a MongoClient in the following ways:

    • By creating a MongoClientSettings instance:

      val mongoClient = MongoClient(MongoClientSettings.builder()
      .applyConnectionString(ConnectionString("mongodb://host1,host2"))
      .readPreference(ReadPreference.secondary())
      .build())
    • By creating a ConnectionString instance:

      val mongoClient = MongoClient("mongodb://host1:27017,host2:27017/?readPreference=secondary")
  • In a MongoDatabase by using the withReadPreference() method:

    val database = mongoClient.getDatabase("test")
    .withReadPreference(ReadPreference.secondary())
  • In a MongoCollection by using the withReadPreference() method:

    val collection = database.getCollection("restaurants")
    .withReadPreference(ReadPreference.secondary())

MongoDatabase and MongoCollection instances are immutable. Calling withReadPreference() on an existing MongoDatabase or MongoCollection instance returns a new instance and does not affect the instance on which the method is called.

In the following example, the collectionWithReadPref instance has the read preference of primaryPreferred whereas the read preference of the collection is unaffected:

val collectionWithReadPref = collection.withReadPreference(ReadPreference.primaryPreferred())

For read operations on replica sets or sharded clusters, applications can configure the read concern at the following levels:

  • In a MongoClient in the following ways:

    • By creating a MongoClientSettings instance:

      val mongoClient = MongoClient(MongoClientSettings.builder()
      .applyConnectionString(ConnectionString("mongodb://host1,host2"))
      .readConcern(ReadConcern.MAJORITY)
      .build())
    • By creating a ConnectionString instance:

      val mongoClient = MongoClient("mongodb://host1:27017,host2:27017/?readConcernLevel=majority")
  • In a MongoDatabase by using the withReadConcern() method:

    val database = mongoClient.getDatabase("test")
    .withReadConcern(ReadConcern.MAJORITY)
  • In a MongoCollection by using the withReadConcern() method:

    val collection = database.getCollection("restaurants")
    .withReadConcern(ReadConcern.MAJORITY)

MongoDatabase and MongoCollection instances are immutable. Calling withReadConcern() on an existing MongoDatabase or MongoCollection instance returns a new instance and does not affect the instance on which the method is called.

In the following example, the collWithReadConcern instance has an AVAILABLE read concern whereas the read concern of the collection is unaffected:

val collWithReadConcern = collection.withReadConcern(ReadConcern.AVAILABLE)

You can build MongoClientSettings, MongoDatabase, or MongoCollection instances to include combinations of read concerns, read preferences, and write concerns.

For example, the following code sets all three at the collection level:

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

Back

Create Indexes