简体   繁体   English

如何使用Reactivemongo在Play框架中处理MongoDB ObjectIds?

[英]How to handle MongoDB ObjectIds in Play framework using Reactivemongo?

I have a basic model with a case class 我有一个带案例类的基本模型

case class Record( id: Option[String], 
                 data: Double,
                 user: String,
                 )

object RecordJsonFormats {
  import play.api.libs.json.Json

  implicit val recordFormat = Json.format[Record]
}

Field user is actually an ObjectId of other module also id is also an ObjectId yet then try to change String type to BSONObjectId macros in play.api.libs.json.Json break... so both user and if saved with object id fields get saved as String not ObjectId . 字段user实际上是其他模块的ObjectIdid也是一个ObjectId然后尝试在play.api.libs.json.Json String类型更改为BSONObjectId宏...所以两个user和如果用对象id字段保存得到保存为String而不是ObjectId

What is the optimal way to operate with ObjectIds in Play framework? 在Play框架中使用ObjectIds的最佳方法是什么?

  • Maybe I should extend play.api.libs.json.Json with BSONObjectId ? 也许我应该延伸play.api.libs.json.JsonBSONObjectId
  • Maybe there is a way to link models and IDs are tracked automatically without a need to declare them in model? 也许有一种方法可以自动跟踪模型和ID,而无需在模型中声明它们?

MongoDB has a default _id field of type ObjectId, which uniquely identifies a document in a given collection. MongoDB有一个ObjectId类型的默认_id字段,它唯一地标识给定集合中的文档。 However, this _id typically does not have a semantic meaning in the context of the application domain. 但是,此_id通常在应用程序域的上下文中没有语义含义。 Therefore, a good practice is to introduce an additional id field as index of documents. 因此,一个好的做法是引入一个额外的id字段作为文档的索引。 This id can simply a Long number, no more or less. 这个id可以只是一个Long数字,不多或少。

Then, you can search documents by id easily, and do not care much about ObjectId. 然后,您可以轻松地按ID搜索文档,而不关心ObjectId。

This, https://github.com/luongbalinh/play-mongo/ , is a sample project using Play 2.4.x and ReactiveMongo. 这个https://github.com/luongbalinh/play-mongo/是一个使用Play 2.4.x和ReactiveMongo的示例项目。 Hopefully, it helps you. 希望它能帮到你。

You can override the default type of _id. 您可以覆盖默认类型_id。 You just need to specify the type you want in the case class. 您只需在案例类中指定所需的类型即可。

import java.util.UUID
import play.api.libs.json._

case class Record (_id: UUID = UUID.randomUUID())

object Record {
  implicit val entityFormat = Json.format[Record]
}

For those using Official Mongo Scala Driver and Play Framework 2.6+, Here's my solution: https://gist.github.com/ntbrock/556a1add78dc287b0cf7e0ce45c743c1 对于使用官方Mongo Scala驱动程序和Play Framework 2.6+的用户,这是我的解决方案: https ://gist.github.com/ntbrock/556a1add78dc287b0cf7e0ce45c743c1

import org.mongodb.scala.bson.ObjectId
import play.api.libs.json._
import scala.util.Try

object ObjectIdFormatJsonMacro extends Format[ObjectId] {

  def writes(objectId: ObjectId): JsValue = JsString(objectId.toString)
  def reads(json: JsValue): JsResult[ObjectId] = json match {
    case JsString(x) => {
      val maybeOID: Try[ObjectId] = Try{new ObjectId(x)}
      if(maybeOID.isSuccess) JsSuccess(maybeOID.get) else {
        JsError("Expected ObjectId as JsString")
      }
    }
    case _ => JsError("Expected ObjectId as JsString")
  }
}

Use it like this in your business objects: 在您的业务对象中使用它:

case class BusinessTime(_id: ObjectId = new ObjectId(), payRate: Double)

object BusinessTime {
  implicit val objectIdFormat = ObjectIdFormatJsonMacro
  implicit val businessTimeFormat = Json.format[BusinessTime]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM