Docs Menu
Docs Home
/ / /
Scala
/

Quick Start

On this page

  • Overview
  • Prerequisites
  • Make a Connection
  • Connect to a Single MongoDB Deployment
  • Access a Database
  • Access a Collection
  • Create a Document
  • Insert a Document
  • Insert One Document
  • Insert Multiple Documents
  • Count Documents in A Collection
  • Query the Collection
  • Find the First Document in a Collection
  • Find All Documents in a Collection
  • Specify a Query Filter
  • Get A Single Document That Matches a Filter
  • Get All Documents That Match a Filter
  • Update Documents
  • Update a Single Document
  • Update Multiple Documents
  • Delete Documents
  • Delete a Single Document That Matches a Filter
  • Delete All Documents That Match a Filter
  • Create Indexes
  • Additional Information

The code examples in this guide come from the QuickTour.scala file in the driver source code GitHub repository.

Note

For instructions about how to install the Scala driver, see the Installation guide.

Note

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

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

  • MongoDB server running on the default port for MongoDB (27017)

  • Driver dependency installed in your project

  • The following import statements:

    import org.mongodb.scala._
    import org.mongodb.scala.model.Aggregates._
    import org.mongodb.scala.model.Filters._
    import org.mongodb.scala.model.Projections._
    import org.mongodb.scala.model.Sorts._
    import org.mongodb.scala.model.Updates._
    import org.mongodb.scala.model._
    import scala.collection.JavaConverters._

Use the MongoClient companion object to make a connection to a running MongoDB deployment.

The MongoClient instance represents a pool of connections to the database. You need only one instance of MongoClient even when using concurrent operation threads.

Important

Typically, you create only one MongoClient instance for a given MongoDB deployment, such as a standalone deployment, replica set, or a sharded cluster, and use the client across your application. However, if you do create multiple instances, keep the following in mind:

  • All resource-usage limits (for example, max connections) apply to each MongoClient instance.

  • To dispose of an instance, call the MongoClient.close() method to clean up resources.

The following example shows several ways to connect to a single MongoDB deployment.

You can connect to a single MongoDB deployment in the following ways:

  • Instantiate a MongoClient object without any parameters to connect to a MongoDB server running on localhost on port 27017:

    val mongoClient: MongoClient = MongoClient()
  • Explicitly specify the hostname to connect to a MongoDB instance running on the specified host on port 27017:

    val mongoClient: MongoClient = MongoClient(
    MongoClientSettings.builder()
    .applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("hostOne")).asJava))
    .build())
  • Explicitly specify the hostname and the port:

    val mongoClient: MongoClient = MongoClient(
    MongoClientSettings.builder()
    .applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("hostOne", 27017)).asJava))
    .build())
  • Specify the ConnectionString:

    val mongoClient: MongoClient = MongoClient("mongodb://hostOne:27017")

Once you have a MongoClient instance connected to a MongoDB deployment, use the MongoClient.getDatabase() method to access a database.

Specify the name of the database to the getDatabase() method. If a database does not exist, MongoDB creates the database when you first store data for that database.

The following example accesses the mydb database:

val database: MongoDatabase = mongoClient.getDatabase("mydb")

MongoDatabase instances are immutable.

Once you have a MongoDatabase instance, use the getCollection() method to access a collection.

Specify the name of the collection to the getCollection() method. If a collection does not exist, MongoDB creates the collection when you first store data for that collection.

For example, using the database instance, the following statement accesses the collection named test in the mydb database:

val collection: MongoCollection[Document] = database.getCollection("test")

MongoCollection instances are immutable.

To create the document by using the driver, use the Document class.

For example, consider the following JSON document:

{
"name" : "MongoDB",
"type" : "database",
"count" : 1,
"info" : { x : 203, y : 102 }
}

To create the document by using the driver, instantiate a Document object:

val doc: Document = Document("_id" -> 0, "name" -> "MongoDB", "type" -> "database",
"count" -> 1, "info" -> Document("x" -> 203, "y" -> 102))

Once you have the MongoCollection object, you can insert documents into the collection.

To insert a document into a collection, use the insertOne() method. Then, use the results() implicit helper to block until the observer is completed:

collection.insertOne(doc).results()

Warning

The driver provides two document types, an immutable Document and a mutable Document.

When using an immutable document, you should explicitly add an _id value, if you need to know that _id value in the future.

If no top-level _id field is specified in the document, MongoDB automatically generates a value and adds this field to the inserted document, but that _id will not be passed back to the user.

Important

In the API, all methods returning an Observable instance are cold streams, meaning that nothing happens until they are subscribed to.

For example, the example below does nothing:

val observable: Observable[InsertOneResult] = collection.insertOne(doc)

The operation happens only when a Observable is subscribed to and data is requested.

observable.subscribe(new Observer[InsertOneResult] {
override def onSubscribe(subscription: Subscription): Unit = subscription.request(1)
override def onNext(result: InsertOneResult): Unit = println(s"onNext $result")
override def onError(e: Throwable): Unit = println("Failed")
override def onComplete(): Unit = println("Completed")
})

Once the document has been inserted, the onNext() method is called and prints onNext followed by the result. Finally, the onComplete() method prints Completed. If there was an error for any reason, the onError() method would print Failed.

To insert multiple documents, you can use the collection's insertMany() method, which takes a list of documents to insert.

The following example adds multiple documents in the following form:

{ "i" : value }

Create the documents in a loop and add them to the documents list:

val documents = (1 to 100) map { i: Int => Document("i" -> i) }

To insert these documents into the collection, pass the list of documents to the insertMany() method:

val insertObservable = collection.insertMany(documents)

The preceding example blocks on the Observable to finish. This ensures that the data is in the database before the next operation runs.

To count the number of documents in a collection, you can use the collection's count() method. The following code should print 101, describing the 100 inserted documents by using insertMany() and the 1 inserted by using insertOne().

Chain the two operations together using a for comprehension. The following code inserts the documents, then counts the number of documents, and prints the results:

val insertAndCount = for {
insertResult <- insertObservable
countResult <- collection.countDocuments()
} yield countResult
println(s"Total # of documents: ${insertAndCount.headResult()}")

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 or pass a filter to query for documents that match the filter criteria.

To return the first document in the collection, use the find() method without any parameters and chain the first() method.

Tip

The find().first() construct is useful for queries that should only match a single document or if you are interested only in the first matching document.

The following example prints the first document found in the collection:

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

The example should print the following document:

{
"_id" : { "$oid" : "551582c558c7b4fbacf16735" },
"name" : "MongoDB",
"type" : "database",
"count" : 1,
"info" : { "x" : 203, "y" : 102 }
}

Note

The _id element has been added automatically by MongoDB to your document and your value will differ from the one shown. MongoDB reserves field names that start with _ and $ for internal use.

To retrieve all of the documents 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 code retrieves and prints all documents in the collection:

collection.find().printResults()

To query for documents that match certain conditions, pass a filter object to the find() method. To facilitate creating filter objects, the driver provides Filters helper methods.

To find the first document in which the field i has the value 71, pass an eq() filter definition to specify the equality condition:

collection.find(equal("i", 71)).first().printHeadResult()

The example prints one document:

{ "_id" : { "$oid" : "..." }, "i" : 71 }

The following example returns and prints all documents in which the value of i is greater than 50:

collection.find(gt("i", 50)).printResults()

To specify a filter for a range, such as 50 < i <= 100, you can use the and() helper:

collection.find(and(gt("i", 50), lte("i", 100))).printResults()

To update documents in a collection, you can use the collection's updateOne() and updateMany() methods.

Pass the following parameters to the methods:

  • Filter object to determine the document or documents to update. To facilitate creating filter objects, the driver provides Filters helper methods. To specify an empty filter and match all documents in the collection, use an empty Document object.

  • Update document that specifies the modifications. To view a list of the available operators, see Update Operators in the Server manual.

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

To update a single document, use the updateOne() method.

The following example updates the first document in which i is 10 and sets the value of i to 110:

collection.updateOne(equal("i", 10), set("i", 110)).printHeadResult("Update Result: ")

To update all documents matching a query filter, use the updateMany() method.

The following example increments the value of i by 100 in all documents in which the value of i is less than 100:

collection.updateMany(lt("i", 100), inc("i", 100)).printHeadResult("Update Result: ")

To delete documents from a collection, you can use the collection's deleteOne() and deleteMany() methods.

Pass a filter object to determine the document or documents to delete. To facilitate creating filter objects, the driver provides Filters helper methods. To specify an empty filter and match all documents in the collection, use an empty Document object.

The delete methods return a DeleteResult that provides information about the operation, including the number of documents deleted.

To delete a single document that matches the filter, use the deleteOne() method.

The following example deletes the first document in which the value of i equals 110:

collection.deleteOne(equal("i", 110)).printHeadResult("Delete Result: ")

To delete all documents that match the filter, use the deleteMany() method.

The following example deletes all documents in which the value of i is greater or equal to 100:

collection.deleteMany(gte("i", 100)).printHeadResult("Delete Result: ")

To create an index on a field or fields, pass an index specification document to the createIndex() method. An index key specification document contains the fields to index and the index type for each field, as modeled by the following document:

Document(<field1> -> <type1>, <field2>, <type2>, ...)

To create an ascending index type, specify 1 for <type>. To create a descending index type, specify -1 for <type>.

The following example creates an ascending index on the i field:

collection.createIndex(Document("i" -> 1)).printHeadResult("Create Index Result: %s")

To view a list of other index types, see the Create Indexes guide.

The Quick Start (Case Class Examples) guide demonstrates how to use the driver with case classes.

You can find additional tutorials in the Tutorials section.

Back

Primer