Статьи

ReactiveMongo: работа с массивом

реактивно-Монго-логотип Я работаю с ReactiveMongo в течение 6 месяцев. Это довольно хорошая реализация драйвера MongoDB для Scala. У меня только одно замечание — у него не такая хорошая документация, как должно быть. Особенно плохую документацию имеют операторы MongoDB. К счастью, оригинальная документация MongoDB исправляет это обстоятельство.

Итак, в этом уроке я хочу продемонстрировать, как вы можете работать с массивами JSON. Я собираюсь изучить операторы $ pull и $ push. После практической части поста, я надеюсь, вы получите ответы на вопросы о том, как добавить элемент в массив с помощью ReactiveMongo (добавить / удалить).

Давайте предположим, что у нас есть такая модель:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
case class Person(_id: Option[BSONObjectID],
                  name: String,
                  phones: Option[Seq[String]])
 
object Person {
  implicit val personWrites: Writes[Person] = (
    (JsPath \ "_id").writeNullable[BSONObjectID] and
    (JsPath \ "name").write[String] and
    (JsPath \ "phones").writeNullable[Seq[String]]
  )(unlift(Person.unapply))
 
  implicit val personReads: Reads[Person] = (
    (JsPath \ "_id").readNullable[BSONObjectID].map(_.getOrElse(BSONObjectID.generate)).map(Some(_)) and
      (JsPath \ "name").read[String] and
      (JsPath \ "phones").readNullable[Seq[String]]
    )(Person.apply _)
}

Как вы видите, в классе дел Person есть поле «Телефоны», которое представлено Seq [String] . Также он обёрнут с помощью Option , но это не так важно. Как мы можем реализовать операции добавления и удаления элементов из массива «Телефоны»? Ответ скрыт в официальных документах MongoDB.

Чтобы реализовать операцию «добавить в массив» с использованием ReactiveMongo, мне нужно:

01
02
03
04
05
06
07
08
09
10
11
def addPhone(name: String, phone: String) = {
    val newPhone = Json.obj(
      "$push" -> Json.obj(
        "phones" -> phone
      )
    )
    collection.update(
      Json.obj("name" -> name),
      newPhone
    )
  }

Обратите внимание на поле «имя». Это должно быть уникальным. Также вы, вероятно, заметили объект Json . Это класс от PlayFramework.

Чтобы удалить какой-то конкретный телефон из массива «телефоны», нам необходимо:

01
02
03
04
05
06
07
08
09
10
11
def removePhone(name: String, phone: String) = {
    val phoneToDelete = Json.obj(
      "$pull" -> Json.obj(
        "phones" -> phone
      )
    )
    collection.update(
      Json.obj("name" -> name),
      phoneToDelete
    )
  }

Я рекомендую обращаться к официальной документации MongoDB каждый раз, когда вы не можете найти то, что вам нужно, в документации ReactiveMongo. Этот подход хорошо работает в большинстве случаев.

Ссылка: ReactiveMongo: Работайте с массивом от нашего партнера по JCG Алексея Зволинского в блоге заметок Фрузенштейна .