Read Operations
On this page
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.
Prerequisites
You must set up the following components to run the code examples in this guide:
A
test.restaurants
collection populated with documents from therestaurants.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.
Connect to a MongoDB Deployment
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.
Query a Collection
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()
Query Filters
To query for documents that match certain conditions, pass a filter
document to the find()
method.
Empty Filter
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()
Filters Helper
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 to2
and less than5
categories
field equals"Bakery"
, or ifcategories
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.
FindObservable
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.
Projections
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.
Sorts
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()
Sort with Projections
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()
Explain
To explain a find operation, call the FindObservable.explain()
method:
collection.find(and(gte("stars", 2), lt("stars", 5), eq("categories", "Bakery"))) .explain() .printResults()
Read Preference
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 thewithReadPreference()
method:val database = mongoClient.getDatabase("test") .withReadPreference(ReadPreference.secondary()) In a
MongoCollection
by using thewithReadPreference()
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())
Read Concern
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 thewithReadConcern()
method:val database = mongoClient.getDatabase("test") .withReadConcern(ReadConcern.MAJORITY) In a
MongoCollection
by using thewithReadConcern()
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)