Как создать собственное средство чтения/записи BSON для вложенных и связанных документов?

Я использую play2-reactivemongo версии 0.11.11 и reactivemongo-play-json. У меня есть следующий класс:

case class Player(
                 id: Option[String],
                 profiles: List[Profile],
                 teams: List[Team],
                 created: Option[DateTime],
                 updated: Option[DateTime]
               ) extends Identity

Атрибут profiles представлен в виде массива, содержащего элементы Profile документов (встроенных). Напротив, атрибут teams представляет собой массив значений _id. Однако при работе с экземплярами Player я хочу обрабатывать List из Team экземпляров, а не _id значений. Как следствие, я думаю, что для этого мне нужны свои BSONReader и BSONWriter.

Мой код выглядит следующим образом:

implicit val PlayerBSONReader = new BSONDocumentReader[Player] {
    def read(doc: BSONDocument): Player =
      Player(
        doc.getAs[BSONObjectID]("_id") map {
          _.stringify
        },

        // attributes 'profiles', 'teams' missing

        doc.getAs[BSONDateTime]("created").map(dt => new DateTime(dt.value)),
        doc.getAs[BSONDateTime]("updated").map(dt => new DateTime(dt.value))
      )
  }


 implicit val PlayerBSONWriter = new BSONDocumentWriter[Player] {
    def write(player: Player): BSONDocument =
      BSONDocument(
        "_id" -> player.id.map(BSONObjectID(_)),

        // attributes 'profiles', 'teams' missing   

        "created" -> player.created.map(date => BSONDateTime(date.getMillis)),
        "updated" -> BSONDateTime(DateTime.now.getMillis)
      )
  }

Как установить атрибуты profiles и teams? Запрашивать базу данных в модели — плохая практика, не так ли? Но как я могу установить экземпляры, имея только значения _id?


person John Doe    schedule 29.05.2016    source источник


Ответы (1)


Там вам нужно убедиться, что экземпляр BSONReader доступен для любого вложенного типа (например, Profile).

То же требование является рекурсивным (например, если у самого Profile есть пользовательские типы в качестве свойств).

Я думаю, вам нужно больше узнать о принципе класса типов, чтобы понять, как он может работать рекурсивно, как для Play JSON Reads|Writes или для классов типов BSON.

person cchantep    schedule 29.05.2016
comment
Хорошо, спасибо, но это отвечает только на часть моего вопроса. Как составить список с экземплярами класса Team, но сохранить только их значения _id в виде массива в соответствующем документе User? - person John Doe; 29.05.2016