Как обрабатывать идентификаторы объектов MongoDB в среде Play с помощью Reactivemongo?

У меня есть базовая модель с классом корпуса

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

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

  implicit val recordFormat = Json.format[Record]
}

Поле user на самом деле является ObjectId другого модуля, также id также является ObjectId, но затем попробуйте изменить тип String на макросы BSONObjectId в play.api.libs.json.Json break... так что и user, и поля id, сохраненные с объектом, сохраняются как String, а не ObjectId.

Каков оптимальный способ работы с ObjectIds в фреймворке Play?

  • Может быть, мне следует расширить play.api.libs.json.Json на BSONObjectId?
  • Может быть, есть способ связать модели, и идентификаторы отслеживаются автоматически без необходимости объявлять их в модели?

person PovilasID    schedule 06.03.2015    source источник


Ответы (3)


Вы можете переопределить тип _id по умолчанию. Вам просто нужно указать тип, который вы хотите в классе case.

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

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

object Record {
  implicit val entityFormat = Json.format[Record]
}
person Rémi Lavolée    schedule 14.11.2016

MongoDB по умолчанию имеет поле _id типа ObjectId, которое однозначно идентифицирует документ в данной коллекции. Однако этот _id обычно не имеет семантического значения в контексте домена приложения. Поэтому хорошей практикой является введение дополнительного поля id в качестве указателя документов. Этот id может быть просто длинным числом, не больше и не меньше.

Затем вы можете легко искать документы по id и не обращать особого внимания на ObjectId.

Это, https://github.com/luongbalinh/play-mongo/, пример проект с использованием Play 2.4.x и ReactiveMongo. Надеюсь, это поможет вам.

person Luong Ba Linh    schedule 31.07.2015

Для тех, кто использует официальный драйвер Mongo Scala и Play Framework 2.6+, вот мое решение: .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")
  }
}

Используйте это так в своих бизнес-объектах:

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

object BusinessTime {
  implicit val objectIdFormat = ObjectIdFormatJsonMacro
  implicit val businessTimeFormat = Json.format[BusinessTime]
}
person Taylor Brockman    schedule 17.10.2018