文档菜单
文档首页
/ / /
Scala
/

快速入门

在本页

  • 概述
  • 先决条件
  • 建立连接
  • 连接到单个 MongoDB 部署
  • 访问数据库
  • 访问集合
  • 创建文档
  • 插入文档
  • 插入单个文档
  • 插入多个文档
  • 计数集合中的文档
  • 查询集合
  • 找到集合中的第一个文档
  • 找到集合中的所有文档
  • 指定查询过滤器
  • 获取匹配过滤器的单个文档
  • 获取匹配过滤器的所有文档
  • 更新文档
  • 更新单个文档
  • 更新多个文档
  • 删除文档
  • 删除匹配过滤器的单个文档
  • 删除匹配过滤器的所有文档
  • 创建索引
  • 更多信息

本指南中的代码示例来自QuickTour.scala 文件,该文件位于驱动源代码 GitHub 仓库中。

注意

有关安装 Scala 驱动的说明,请参阅安装指南

注意

本指南使用的是Observable 隐式转换,如《快速入门指南》中所述。

您必须设置以下组件才能运行本指南中的代码示例

  • MongoDB服务器正在默认端口(27017)上运行

  • 您的项目中已安装驱动依赖

  • 以下导入语句

    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._

使用MongoClient 伴生对象以连接到运行的MongoDB部署。

MongoClient 实例表示数据库连接池。即使在使用并发操作线程的情况下,也只需要一个 MongoClient 实例。

重要

通常,您只为给定的MongoDB部署(如独立部署、副本集或分片集群)创建一个 MongoClient 实例,并在您的应用程序中使用该客户端。但是,如果您创建了多个实例,请注意以下事项

  • 所有资源使用限制(例如,最大连接数)适用于每个 MongoClient 实例。

  • 要销毁实例,请调用 MongoClient.close() 方法来清理资源。

以下示例展示了连接到单个MongoDB部署的几种方法。

您可以通过以下方式连接到单个MongoDB部署:

  • 实例化一个不带有任何参数的 MongoClient 对象,以连接到运行在本地主机上的MongoDB服务器,端口号为 27017

    val mongoClient: MongoClient = MongoClient()
  • 明确指定 hostname 以连接到指定主机上的MongoDB实例,端口号为 27017

    val mongoClient: MongoClient = MongoClient(
    MongoClientSettings.builder()
    .applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("hostOne")).asJava))
    .build())
  • 明确指定 hostnameport

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

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

一旦您有一个连接到MongoDB部署的 MongoClient 实例,使用 MongoClient.getDatabase() 方法访问数据库。

将数据库名称指定给 getDatabase() 方法。如果数据库不存在,MongoDB会在您首次存储该数据库数据时创建该数据库。

以下示例访问 mydb 数据库

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

MongoDatabase 实例是不可变的。

一旦您有一个 MongoDatabase 实例,使用 getCollection() 方法访问集合。

将集合名称指定给getCollection()方法。如果不存在该集合,MongoDB会在您首次为该集合存储数据时创建该集合。

例如,使用数据库实例,以下语句访问mydb数据库中名为test的集合

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

MongoCollection实例是不可变的。

要使用驱动程序创建文档,请使用Document类。

例如,考虑以下JSON文档

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

要使用驱动程序创建文档,请实例化一个Document对象

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

一旦您拥有了 MongoCollection 对象,您就可以将文档插入到集合中。

要将文档插入集合,请使用 insertOne() 方法。然后,使用隐式辅助函数 results() 以阻塞方式等待观察者完成。

collection.insertOne(doc).results()

警告

驱动程序提供了两种文档类型:不可变的 Document 和可变的 Document

当使用不可变文档时,您应该显式添加一个 _id 值,如果您以后需要知道该 _id 值。

如果文档中未指定顶级 _id 字段,MongoDB 会自动生成一个值并将其添加到插入的文档中,但该 _id 不会传递回用户。

重要

在 API 中,所有返回 Observable 实例的方法都是冷流,这意味着直到它们被订阅之前什么都不会发生。

例如,以下示例不会做任何事情

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

只有在订阅 Observable 并请求数据时,操作才会发生。

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")
})

文档插入后,将调用 onNext() 方法并打印 onNext 后跟结果。最后,打印 Completed。如果由于任何原因出现错误,则 onError() 方法将打印 Failed

要插入多个文档,可以使用集合的insertMany()方法,它接受要插入的文档列表。

以下示例以以下形式添加多个文档

{ "i" : value }

在循环中创建文档并将它们添加到documents列表中

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

要将这些文档插入集合,将文档列表传递给insertMany()方法

val insertObservable = collection.insertMany(documents)

前面的示例在Observable上阻塞以完成。这确保在运行下一个操作之前数据已在数据库中。

要统计集合中的文档数量,可以使用集合的count()方法。以下代码应打印101,描述了通过使用insertMany()插入的100个文档和通过使用insertOne()插入的1个文档。

使用for循环将两个操作连接起来。以下代码插入文档,然后统计文档数量并打印结果

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

要查询集合,可以使用集合的find()方法。您可以不带任何参数调用此方法来查询集合中的所有文档,或者传递一个过滤器来查询符合过滤器条件的文档。

要返回集合中的第一个文档,请使用find()方法不带任何参数,并链式调用first()方法。

提示

find().first()构造对于只匹配单个文档的查询或您只对第一个匹配的文档感兴趣时非常有用。

以下示例将打印出找到的第一个文档

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

此示例应打印以下文档

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

注意

_id元素已由MongoDB自动添加到您的文档中,您的值将与显示的值不同。MongoDB为内部使用保留了以_$开头的字段名。

要检索集合中的所有文档,请使用 find() 方法。该方法返回一个 FindObservable 实例,该实例提供了流畅的接口,用于链式调用或控制查找操作。以下代码检索并打印集合中的所有文档

collection.find().printResults()

要查询符合特定条件的文档,请将过滤器对象传递给 find() 方法。为了便于创建过滤器对象,驱动程序提供了 Filters 辅助方法。

要查找字段 i 的值等于 71 的第一个文档,请传递一个 eq() 过滤器定义来指定相等条件

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

示例打印一个文档

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

以下示例返回并打印所有i值大于50的文档

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

要指定范围过滤器,例如50 < i <= 100,可以使用and()辅助函数

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

要更新集合中的文档,可以使用集合的updateOne()updateMany()方法。

传递以下参数到方法

  • 过滤器对象,用于确定要更新的文档或文档。为了便于创建过滤器对象,驱动程序提供了Filters辅助方法。要指定空过滤器并匹配集合中的所有文档,请使用空的Document对象。

  • 指定要修改的更新文档。要查看可用操作员的列表,请参阅服务器手册中的更新操作符

更新方法返回一个UpdateResult类型,该类型提供有关操作的信息,包括更新修改的文档数。

要更新单个文档,请使用 updateOne() 方法。

以下示例更新第一个 i 值为 10 的文档,并将 i 的值设置为 110

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

要更新与查询过滤器匹配的所有文档,请使用 updateMany() 方法。

以下示例将所有 i 值小于 100 的文档中的 i 值增加 100

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

要从集合中删除文档,您可以使用集合的 deleteOne()deleteMany() 方法。

传递一个过滤器对象以确定要删除的文档。为了方便创建过滤器对象,驱动程序提供了 Filters 辅助方法。要指定一个空过滤器以匹配集合中的所有文档,请使用一个空的 Document 对象。

删除方法返回一个 DeleteResult 对象,该对象提供有关操作的信息,包括删除的文档数。

要删除匹配过滤器的单个文档,请使用 deleteOne() 方法。

以下示例删除了第一个 i 的值等于 110 的文档

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

要删除所有匹配过滤器的文档,请使用 deleteMany() 方法。

以下示例删除了所有 i 的值大于或等于 100 的文档

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

要在字段或字段上创建索引,将索引规范文档传递给 createIndex() 方法。索引键规范文档包含要索引的字段和每个字段的索引类型,如以下文档所示

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

要创建一个升序索引类型,请将 1 指定给 <type>。要创建一个降序索引类型,请将 -1 指定给 <type>

以下示例在 i 字段上创建了一个升序索引

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

要查看其他索引类型的列表,请参阅创建索引指南。

快速入门(案例类示例)指南演示了如何使用驱动程序与案例类一起使用。

您可以在教程部分找到更多教程。

返回

入门