Reactivemongo - BSONObjectID 和 BSONDateTime 插入
Reactivemongo - BSONObjectID and BSONDateTime Insertion
我正在使用 play2.5 + play2-reactivemongo 0.12.3。
BSONObjectID 作为数组插入,BSONDateTime 作为 NumberLong 在 mongoDB 上插入,代码如下。
> db.Example.find()
{ "_id" : { "array" : [ 89, 55, -10, 60, -40, 0, 0, -61, 0, -94, 126, 23 ] }, "created" : NumberLong("1496839744818") }
我希望将 BSONObjectID 作为 ObjectID 插入,将 DateTime 作为 BSONDateTime 插入。
是否可以使用类型参数?
TemporalModel.scala
trait TemporalModel {
var _id: Option[BSONObjectID]
var created: Option[DateTime]
}
Example.scala
import org.joda.time.DateTime
...
case class Example(
var_id: Option[BSONObjectID],
str: String,
var created: Option[DateTime]
) extends TemporalModel
object Example {
//implicit val objectIdRead: Reads[BSONObjectID] =
val objectIdRead: Reads[BSONObjectID] =
(__ \ "$oid").read[String].map { oid =>
BSONObjectID(oid)
}
//implicit val objectIdWrite: Writes[BSONObjectID] = new Writes[BSONObjectID] {
val objectIdWrite: Writes[BSONObjectID] = new Writes[BSONObjectID] {
def writes(objectId: BSONObjectID): JsValue = Json.obj(
"$oid" -> objectId.stringify
)
}
//implicit val dateTimeRead: Reads[DateTime] =
val dateTimeRead: Reads[DateTime] =
(__ \ "$date").read[Long].map { dateTime =>
new DateTime(dateTime)
}
//implicit val dateTimeWrite: Writes[DateTime] = new Writes[DateTime] {
val dateTimeWrite: Writes[DateTime] = new Writes[DateTime] {
def writes(dateTime: DateTime): JsValue = Json.obj(
"$date" -> dateTime.getMillis
)
}
implicit val objectIdFormats = Format(objectIdRead, objectIdWrite)
implicit val dateTimeFormats = Format(dateTimeRead, dateTimeWrite)
//implicit val bsonObjectIDJsonFormat = Json.format[BSONObjectID]
implicit val exampleJsonFormat = Json.format[Example]
def apply(str: String): Example = {
new Example(null, str, null)
}
}
BaseDAO.scala
class BaseDAO[T] {
...
val collectionName: String
lazy val collection: Future[JSONCollection] = reactiveMongoApi.database.map(_.collection(collectionName))
def toJs[K : Writes](o: K) = Json.toJson(o).as[JsObject]
def insert(document: T)(implicit writer: Writes[T]): Future[T] = {
document._id = Some(BSONObjectID.generate)
document.created = Some(DateTime.now)
collection.flatMap(_.insert(toJs(document)))
}
}
ExampleDAO.scala
trait ExampleDAO extends BaseDAO[Example]
class ExampleDAOImpl @Inject() (val reactiveMongoApi: ReactiveMongoApi)
extends ExampleDAO {
val collectionName = "example"
}
问题是范围内的隐式太多。但是,由于这些在宏中已解决,因此似乎没有编译错误。
你应该做什么:
- 删除
Reads
和 Writes
前面的所有 implicit
修饰符,用于 BSONObjectID
和 DateTime
- 删除
bsonObjectIDJsonFormat
(与 objectIdFormats
具有相同的类型,因此编译器不应允许这样做)
我正在使用 play2.5 + play2-reactivemongo 0.12.3。
BSONObjectID 作为数组插入,BSONDateTime 作为 NumberLong 在 mongoDB 上插入,代码如下。
> db.Example.find()
{ "_id" : { "array" : [ 89, 55, -10, 60, -40, 0, 0, -61, 0, -94, 126, 23 ] }, "created" : NumberLong("1496839744818") }
我希望将 BSONObjectID 作为 ObjectID 插入,将 DateTime 作为 BSONDateTime 插入。 是否可以使用类型参数?
TemporalModel.scala
trait TemporalModel {
var _id: Option[BSONObjectID]
var created: Option[DateTime]
}
Example.scala
import org.joda.time.DateTime
...
case class Example(
var_id: Option[BSONObjectID],
str: String,
var created: Option[DateTime]
) extends TemporalModel
object Example {
//implicit val objectIdRead: Reads[BSONObjectID] =
val objectIdRead: Reads[BSONObjectID] =
(__ \ "$oid").read[String].map { oid =>
BSONObjectID(oid)
}
//implicit val objectIdWrite: Writes[BSONObjectID] = new Writes[BSONObjectID] {
val objectIdWrite: Writes[BSONObjectID] = new Writes[BSONObjectID] {
def writes(objectId: BSONObjectID): JsValue = Json.obj(
"$oid" -> objectId.stringify
)
}
//implicit val dateTimeRead: Reads[DateTime] =
val dateTimeRead: Reads[DateTime] =
(__ \ "$date").read[Long].map { dateTime =>
new DateTime(dateTime)
}
//implicit val dateTimeWrite: Writes[DateTime] = new Writes[DateTime] {
val dateTimeWrite: Writes[DateTime] = new Writes[DateTime] {
def writes(dateTime: DateTime): JsValue = Json.obj(
"$date" -> dateTime.getMillis
)
}
implicit val objectIdFormats = Format(objectIdRead, objectIdWrite)
implicit val dateTimeFormats = Format(dateTimeRead, dateTimeWrite)
//implicit val bsonObjectIDJsonFormat = Json.format[BSONObjectID]
implicit val exampleJsonFormat = Json.format[Example]
def apply(str: String): Example = {
new Example(null, str, null)
}
}
BaseDAO.scala
class BaseDAO[T] {
...
val collectionName: String
lazy val collection: Future[JSONCollection] = reactiveMongoApi.database.map(_.collection(collectionName))
def toJs[K : Writes](o: K) = Json.toJson(o).as[JsObject]
def insert(document: T)(implicit writer: Writes[T]): Future[T] = {
document._id = Some(BSONObjectID.generate)
document.created = Some(DateTime.now)
collection.flatMap(_.insert(toJs(document)))
}
}
ExampleDAO.scala
trait ExampleDAO extends BaseDAO[Example]
class ExampleDAOImpl @Inject() (val reactiveMongoApi: ReactiveMongoApi)
extends ExampleDAO {
val collectionName = "example"
}
问题是范围内的隐式太多。但是,由于这些在宏中已解决,因此似乎没有编译错误。
你应该做什么:
- 删除
Reads
和Writes
前面的所有implicit
修饰符,用于BSONObjectID
和DateTime
- 删除
bsonObjectIDJsonFormat
(与objectIdFormats
具有相同的类型,因此编译器不应允许这样做)