|
| 1 | ++++ |
| 2 | +date = "2015-03-17T15:36:56Z" |
| 3 | +title = "Quick Tour - case classes" |
| 4 | +[menu.main] |
| 5 | + parent = "Getting Started" |
| 6 | + identifier = "Quick Tour - case classes" |
| 7 | + weight = 35 |
| 8 | + pre = "<i class='fa'></i>" |
| 9 | ++++ |
| 10 | + |
| 11 | +# Quick Tour with case classes |
| 12 | + |
| 13 | +The following code snippets come from the `QuickTourCaseClass.scala` example code that can be found with the |
| 14 | +[driver source]({{< srcref "examples/src/test/scala/tour/QuickTourCaseClass.scala">}}). |
| 15 | + |
| 16 | +{{% note class="important" %}} |
| 17 | +This follows on from the [quick tour]({{< relref "getting-started/quick-tour.md" >}}). |
| 18 | + |
| 19 | +See the [Bson macros]({{< relref "bson/macros.md" >}}) documentation for in-depth information about using macros for configuring case class |
| 20 | +support with your `MongoCollection`. |
| 21 | +{{% /note %}} |
| 22 | + |
| 23 | + |
| 24 | +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 |
| 25 | +class and companion object: |
| 26 | + |
| 27 | +```scala |
| 28 | +import org.mongodb.scala.bson.ObjectId |
| 29 | +object Person { |
| 30 | + def apply(firstName: String, lastName: String): Person = |
| 31 | + Person(new ObjectId(), firstName, lastName) |
| 32 | +} |
| 33 | +case class Person(_id: ObjectId, firstName: String, lastName: String) |
| 34 | +``` |
| 35 | + |
| 36 | +{{% note %}} |
| 37 | +You'll notice in the companion object we automatically assign a `_id` when creating new instances that don't include it. The `_id` is the |
| 38 | +primary key for a document, so by having a `_id` field in the case class it allows access to the primary key. |
| 39 | +{{% /note %}} |
| 40 | + |
| 41 | +## Configuring case classes |
| 42 | + |
| 43 | +Then when using `Person` with our collection we must have a `Codec` that can convert it to and from `BSON`. The `bson` package provides |
| 44 | +macros that automatically generate a codec at compile time. In the following example we create a new `CodecRegistry` that includes a |
| 45 | +codec for the `Person` case class: |
| 46 | + |
| 47 | + |
| 48 | +```scala |
| 49 | +import org.mongodb.scala.bson.codecs.Macros._ |
| 50 | +import org.mongodb.scala.bson.codecs.DEFAULT_CODEC_REGISTRY |
| 51 | +import org.bson.codecs.configuration.CodecRegistries.{fromRegistries, fromProviders} |
| 52 | + |
| 53 | +val codecRegistry = fromRegistries(fromProviders(classOf[Person]), DEFAULT_CODEC_REGISTRY ) |
| 54 | +``` |
| 55 | + |
| 56 | +Once we have the `codecRegistry` configured then we can use that to create a `MongoCollection[Person]`. In the following we get the `test` collection on the `mydb` database. Notice the `codecRegistry` is set at the database level, it could have been set when creating the `MongoClient` or even via the `MongoCollection.withCodecRegistry` method. |
| 57 | + |
| 58 | +```scala |
| 59 | +// To directly connect to the default server localhost on port 27017 |
| 60 | +val mongoClient: MongoClient = MongoClient() |
| 61 | +val database: MongoDatabase = mongoClient.getDatabase("mydb").withCodecRegistry(codecRegistry) |
| 62 | +val collection: MongoCollection[Person] = database.getCollection("test") |
| 63 | +``` |
| 64 | + |
| 65 | +## Insert a person |
| 66 | + |
| 67 | +Once you have the collection object, you can insert `Person` instances into the collection: |
| 68 | + |
| 69 | +```scala |
| 70 | +val person: Person = Person("Ada", "Lovelace") |
| 71 | +collection.insertOne(person).results() |
| 72 | +``` |
| 73 | + |
| 74 | +## Add multiple instances |
| 75 | + |
| 76 | +To add multiple `Person` instances, you can use the `insertMany()` method and print the results of the operation: |
| 77 | + |
| 78 | +```scala |
| 79 | +val people: Seq[Person] = Seq( |
| 80 | + Person("Charles", "Babbage"), |
| 81 | + Person("George", "Boole"), |
| 82 | + Person("Gertrude", "Blanch"), |
| 83 | + Person("Grace", "Hopper"), |
| 84 | + Person("Ida", "Rhodes"), |
| 85 | + Person("Jean", "Bartik"), |
| 86 | + Person("John", "Backus"), |
| 87 | + Person("Lucy", "Sanders"), |
| 88 | + Person("Tim", "Berners Lee"), |
| 89 | + Person("Zaphod", "Beeblebrox") |
| 90 | +) |
| 91 | +collection.insertMany(people).printResults() |
| 92 | +``` |
| 93 | +And we should the following output: |
| 94 | + |
| 95 | +``` |
| 96 | +The operation completed successfully |
| 97 | +``` |
| 98 | + |
| 99 | +## Querying the collection |
| 100 | + |
| 101 | +Use the [find()]({{< apiref "org.mongodb.scala.MongoCollection@find[C](filter:org.bson.conversions.Bson)(implicite:org.mongodb.scala.Helpers.DefaultsTo[C,org.mongodb.scala.collection.immutable.Document],implicitct:scala.reflect.ClassTag[C]):org.mongodb.scala.FindObservable[C]">}}) |
| 102 | +method to query the collection. |
| 103 | + |
| 104 | +### Find the First Person in a Collection |
| 105 | + |
| 106 | +You can query the collection in the same as shown in the [quick tour]({{< relref "getting-started/quick-tour.md" >}}). |
| 107 | + |
| 108 | +```scala |
| 109 | +collection.find().first().printHeadResult() |
| 110 | +``` |
| 111 | + |
| 112 | +The example will print the first `Person` in the database: |
| 113 | + |
| 114 | +``` |
| 115 | +Person(58dd0a68218de22333435fa4, Ada, Lovelace) |
| 116 | +``` |
| 117 | + |
| 118 | +### Find all people in the collection |
| 119 | + |
| 120 | +To retrieve all the people in the collection, we will use the |
| 121 | +`find()` method. The `find()` method returns a `FindObservable` instance that |
| 122 | +provides a fluent interface for chaining or controlling find operations. |
| 123 | +The following code retrieves all documents in the collection and prints them out |
| 124 | +(101 documents). Using the `printResults()` implicit we block until the observer is completed and then print each result: |
| 125 | +```scala |
| 126 | +collection.find().printResults() |
| 127 | +``` |
| 128 | + |
| 129 | + |
| 130 | +## Get a single person with a query filter |
| 131 | + |
| 132 | +We can create a filter to pass to the find() method to get a subset of |
| 133 | +the documents in our collection. For example, if we wanted to find the |
| 134 | +document for which the value of the "firstName" is "Ida", we would do the |
| 135 | +following: |
| 136 | + |
| 137 | +```scala |
| 138 | +import org.mongodb.scala.model.Filters._ |
| 139 | + |
| 140 | +collection.find(equal("firstName", "Ida")).first().printHeadResult() |
| 141 | +``` |
| 142 | + |
| 143 | +will eventually print just one Person: |
| 144 | + |
| 145 | +``` |
| 146 | +Person(58dd0a68218de22333435fa4, Ida, Rhodes) |
| 147 | +``` |
| 148 | + |
| 149 | +{{% note %}} |
| 150 | +Use the [`Filters`]({{< relref "builders/filters.md">}}), [`Sorts`]({{< relref "builders/sorts.md">}}), |
| 151 | +[`Projections`]({{< relref "builders/projections.md">}}) and [`Updates`]({{< relref "builders/updates.md">}}) |
| 152 | +helpers for simple and concise ways of building up queries. |
| 153 | +{{% /note %}} |
| 154 | + |
| 155 | +## Get a set of people with a query |
| 156 | + |
| 157 | +We can use the query to get a set of people from our collection. For |
| 158 | +example, if we wanted to get all documents where the `firstName` starts with `G` and sort by `lastName` we could |
| 159 | +write: |
| 160 | + |
| 161 | +```scala |
| 162 | +collection.find(regex("firstName", "^G")).sort(ascending("lastName")).printResults() |
| 163 | +``` |
| 164 | + |
| 165 | +Which will print out the Person instances for Gertrude, George and Grace. |
| 166 | + |
| 167 | +## Updating documents |
| 168 | + |
| 169 | +There are numerous [update operators](http://docs.mongodb.org/manual/reference/operator/update-field/) |
| 170 | +supported by MongoDB. We can use the [Updates]({{< apiref "org.mongodb.scala.model.Updates$">}}) helpers to help update documents in the database. |
| 171 | + |
| 172 | +In the following we update and correct the hyphenation of Tim Berners-Lee: |
| 173 | + |
| 174 | +```scala |
| 175 | +collection.updateOne(equal("lastName", "Berners Lee"), set("lastName", "Berners-Lee")).printHeadResult("Update Result: ") |
| 176 | +``` |
| 177 | + |
| 178 | +The update methods return an [`UpdateResult`]({{< coreapiref "com/mongodb/client/result/UpdateResult.html">}}), |
| 179 | +which provides information about the operation including the number of documents modified by the update. |
| 180 | + |
| 181 | +## Deleting documents |
| 182 | + |
| 183 | +To delete at most a single document (may be 0 if none match the filter) use the [`deleteOne`]({{< apiref "org.mongodb.scala.MongoCollection@deleteOne(filter:org.bson.conversions.Bson):org.mongodb.scala.Observable[org.mongodb.scala.result.DeleteResult]">}}) |
| 184 | +method: |
| 185 | + |
| 186 | +```scala |
| 187 | +collection.deleteOne(equal("firstName", "Zaphod")).printHeadResult("Delete Result: ") |
| 188 | +``` |
| 189 | + |
| 190 | +As you can see the API allows for easy use of CRUD operations with case classes. See the [Bson macros]({{< relref "bson/macros.md" >}}) |
| 191 | +documentation for further information about the macros. |
0 commit comments