Scala ReactiveMongo пример.Пропущенные операции или последствия - PullRequest
1 голос
/ 20 сентября 2019

Я пытаюсь использовать responsetivemongo getstarted , чтобы выяснить, как его использовать.Я использую:

  • scala 2.13.0
  • "org.reactivemongo" %% "reactivemongo" % "0.18.6"

Для меня я сделал, как это требовалось после документации.Но проблемы компиляции возникали рядом с каждой операцией БД (personCollection: insert, update, find).Я не понимаю, как исправить их из-за недостатка знаний / опыта в scala.

Код:

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.Try
import reactivemongo.api.{Cursor, DefaultDB, MongoConnection, MongoDriver}
import reactivemongo.bson.{BSONDocumentReader, BSONDocumentWriter, Macros, document}

object GetStartedWithMongo {
  def main(args: Array[String]): Unit = {
    val age = 99
    val person: Person = Person("firstName", "lastName", age)
    createPerson(person)
    findPersonByAge(age).andThen {
      case x => println(s"loaded data: $x")
    }

    println("completed")
  }

  val database = "personDb"
  val driver = new MongoDriver
  val mongoUri = "mongodb://localhost:27017/mydb?authMode=scram-sha1"
  // Connect to the database: Must be done only once per application
  val parsedUri: Try[MongoConnection.ParsedURI] =
    MongoConnection.parseURI(mongoUri)
  val connection: Try[MongoConnection] = parsedUri.map(driver.connection(_))
  val futureConnection: Future[MongoConnection] = Future.fromTry(connection)

  //  val db = connection(database)
  val db: Future[DefaultDB] = futureConnection.flatMap(_.database(database))

  //  def personCollection: Future[List[Person]] = db.map(_.collection("person"))
  def personCollection = db.map(_.collection("person"))

  // use personWriter
  def createPerson(person: Person): Future[Unit] =
    personCollection.flatMap(_.insert.one(person).map(_ => {}))
//                             ^^^^^^ - compilation issue

  // Write Documents: insert or update

  implicit def personWriter: BSONDocumentWriter[Person] = Macros.writer[Person]
  // or provide a custom one

  def updatePerson(person: Person): Future[Int] = {
    val selector =
      document("firstName" -> person.firstName, "lastName" -> person.lastName)

    // Update the matching person
    personCollection.flatMap(_.update.one(selector, person).map(_.n))
//                             ^^^^^^ - compilation issue

  }

  implicit def personReader: BSONDocumentReader[Person] = Macros.reader[Person]
  // or provide a custom one

  def findPersonByAge(age: Int): Future[List[Person]] =
    personCollection.flatMap(
      _.find(document("age" -> age)). // query builder
//      ^^^^ - compilation issue

      cursor[Person](). // using the result cursor
      collect[List](-1, Cursor.FailOnError[List[Person]]())
    )
  // ... deserializes the document using personReader

  // Custom persistent types
  case class Person(firstName: String, lastName: String, age: Int)
}

PS

Чтобы было проще рассмотреть и исправитьПроблема Я поделился этим экспериментальным модулем через git ( класс ).

Ответы [ 2 ]

1 голос
/ 20 сентября 2019

Для компиляции добавьте явную аннотацию типа к personCollection:

def personCollection: Future[BSONCollection] = db.map(db => db.collection("person"))
0 голосов
/ 20 сентября 2019

Проверяя другие reactivemongo учебные страницы, мы можем указать тип dbCollection.Тип возврата не Future[List[Person]] или Future[Person] или Future[Nothing].Это Future [BSONCollection] .Если тип добавлен, проблемы с компиляцией устранены.

Начиная проект, мы можем найти в сообщениях терминала, что что-то пропущено.Чтобы исправить пропущенную зависимость, я добавил в проект slf4j library ("org.slf4j" % "slf4j-api" % "1.7.28")

Так что, если я попробую это:

def main(args: Array[String]): Unit = {
  val age = 93
  val person: Person = Person("firstName", "lastName", age)
  createPerson(person)
  findPersonByAge(age).andThen {
    case x => println(s"loaded data: $x")
  }

  println("completed")
}

результат, как и ожидалось в общем:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
completed
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
loaded data: Success(List(Person(firstName,lastName,93)))

Git обновлен также.

...