Quick Tour with case classes

The following code snippets come from the QuickTourCaseClass.scala example code that can be found with the driver source.

important

This follows on from the quick tour.

See the Bson macros documentation for in-depth information about using macros for configuring case class support with your MongoCollection.

First we’ll create the case class we want to use to represent the documents in the collection. In the following we create a Person case class and companion object:

import org.mongodb.scala.bson.ObjectId
object Person {
  def apply(firstName: String, lastName: String): Person =
    Person(new ObjectId(), firstName, lastName)
}
case class Person(_id: ObjectId, firstName: String, lastName: String)

Note

You’ll notice in the companion object the apply method can automatically assign a _id when creating new instances that don’t include it. In MongoDB the _id field represents the primary key for a document, so by having a _id field in the case class it allows access to the primary key.

Configuring case classes

Then when using Person with a collection, there must be a Codec that can convert it to and from BSON. The org.mongodb.scala.bson.codecs.Macros companion object provides macros that can automatically generate a codec for case classes at compile time. In the following example we create a new CodecRegistry that includes a codec for the Person case class:

import org.mongodb.scala.bson.codecs.Macros._
import org.mongodb.scala.bson.codecs.DEFAULT_CODEC_REGISTRY
import org.bson.codecs.configuration.CodecRegistries.{fromRegistries, fromProviders}

val codecRegistry = fromRegistries(fromProviders(classOf[Person]), DEFAULT_CODEC_REGISTRY )

Once the codecRegistry is configured, the next step is to create a MongoCollection[Person]. The following example uses test collection on the mydb database.

// To directly connect to the default server localhost on port 27017
val mongoClient: MongoClient = MongoClient()
val database: MongoDatabase = mongoClient.getDatabase("mydb").withCodecRegistry(codecRegistry)
val collection: MongoCollection[Person] = database.getCollection("test")

Note

The codecRegistry can be set when creating a MongoClient, at the database level or at the collection level. The API is flexible, allowing for different CodecRegistries as required.

Insert a person

With the correctly configured MongoCollection, inserting Person instances into the collection is simple:

val person: Person = Person("Ada", "Lovelace")
collection.insertOne(person).results()

Add multiple instances

To add multiple Person instances, use the insertMany(). The following uses the printResults() implicit and blocks until the observer is completed and then prints each result:

val people: Seq[Person] = Seq(
  Person("Charles", "Babbage"),
  Person("George", "Boole"),
  Person("Gertrude", "Blanch"),
  Person("Grace", "Hopper"),
  Person("Ida", "Rhodes"),
  Person("Jean", "Bartik"),
  Person("John", "Backus"),
  Person("Lucy", "Sanders"),
  Person("Tim", "Berners Lee"),
  Person("Zaphod", "Beeblebrox")
)
collection.insertMany(people).printResults()

It will output the following message:

The operation completed successfully

Querying the collection

Use the find() method to query the collection.

Find the first person in a collection

Querying the collection is the same as shown in the quick tour:

collection.find().first().printHeadResult()

The example will print the first Person in the database:

Person(58dd0a68218de22333435fa4, Ada, Lovelace)

Find all people in the collection

To retrieve all the people in the collection, use the find() method. The find() method returns a FindObservable instance that provides a fluent interface for chaining or controlling find operations. The following uses prints all the people in the collection:

collection.find().printResults()

Get a single person with a query filter

To return a subset of the documents in our collection, pass a filter to the find() method . For example, the following will return the first Person whose first name is Ida:

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

collection.find(equal("firstName", "Ida")).first().printHeadResult()

This will print:

Person(58dd0a68218de22333435fa4, Ida, Rhodes)

Note

Use the Filters, Sorts, Projections and Updates helpers for simple and concise ways of building up queries.

Get a set of people with a query

The following filter will find all Person instances where the firstName starts with G, sorted by lastName:

collection.find(regex("firstName", "^G")).sort(ascending("lastName")).printResults()

Which will print out the Person instances for Gertrude, George and Grace.

Updating documents

There are numerous update operators supported by MongoDB. Use the Updates helpers to help update documents in the database.

The following update corrects the hyphenation for Tim Berners-Lee:

collection.updateOne(equal("lastName", "Berners Lee"), set("lastName", "Berners-Lee")).printHeadResult("Update Result: ")

The update methods return an UpdateResult, which provides information about the operation including the number of documents modified by the update.

Deleting documents

To delete at most a single document (may be 0 if none match the filter) use the deleteOne method:

collection.deleteOne(equal("firstName", "Zaphod")).printHeadResult("Delete Result: ")

As you can see the API allows for easy use of CRUD operations with case classes. See the Bson macros documentation for further information about the macros.