0

I am new in this Scala world and I would be thankful if someone could help me. So, I am building a Scala application that saves files to a mongodb database using the MongoDB Scala driver. I was using Casbah before, but since it says in the mongodb official website that it is a legacy driver and my project has just started, I decided to move to the official driver.

So my application saves an Object that contains an id and this id comes to a collection from MongoDB called "Sequences". Every time I wanna save an object from this class, it first will get the last id from the sequence and increment it by one.

When I was using Casbah, this code used to do the job:

def getSequenceId(seqName: String): Int = {
  val query = MongoDBObject("seq_id" -> seqName);
  val result = MongoFactory.SequenceCollection
                          .findAndModify(query, $inc("nextId" -> 1)) 
  val nbr = result.get("nextId");
  return nbr.toString.toDouble.toInt;
}

The problem is that with the MongoDB Scala driver, you have to use the Observable pattern for that and I am a bit confused.

So far, I managed to make a code like this:

def getSequenceId(seqName: String): Int = {
  val query = new BsonDocument("seq_id", new BsonString(seqName))
  val resultado = NewMongo.SequenceCollection.findOneAndUpdate(query,inc("nextId",1)).collect()          
   .subscribe(new Observer[Seq[Document]] {
      override def onNext(result: Seq[Document]): Unit = println(s"UPDATED ${result(0)}")
      override def onError(e: Throwable): Unit = println(s"Failed due to $e")
      override def onComplete(): Unit = println("Completed")
  })
}

The problem is that this is my first time to use this Observer pattern and I don't know how to get the modified document to get the last id. I searched in a lot of websites about it and I couldn't find an answer. In most cases I only found solutions for Casbah.

Thanks

Israel Zinc
  • 2,713
  • 2
  • 18
  • 30

2 Answers2

1

Just for the sake of clarification, I found out how to do it myself:

def getSequenceId(seqName: String): Int = {

  val query = new BsonDocument("seq_id", new BsonString(seqName))    
  val resultado = NewMongo.AibodSequence.findOneAndUpdate(query,inc("nextId",1))    
  resultado.subscribe(new Observer[Document] {        
    override def onNext(result: Document): Unit ={}
    override def onError(e: Throwable): Unit ={}
    override def onComplete(): Unit = {}
  })
  val awaitedR = Await.result(resultado.toFuture, Duration.Inf).asInstanceOf[List[Document]](0)

  val ret = awaitedR.get("nextId").getOrElse(0).asInstanceOf[BsonDouble].intValue();

  return ret;  
}

Apparently you can convert the result observer into a future and wait for its return using the Await function as I did. Then you can manipulate the result as you wish.

Israel Zinc
  • 2,713
  • 2
  • 18
  • 30
  • I am a bit late to the game but is there a reason you didn't simply collect and subscribe in this case to get the data as a Seq? I am not sure how they built Observables behind the doors but surely all this casting have downsides – sinanspd Aug 08 '18 at 04:58
0

You should use ReactiveMongo .It's simply the best scala driver for mongo out there. And if you are using play framework, use the ReactiveMongo play extension.

oblivion
  • 5,928
  • 3
  • 34
  • 55
  • Hello oblivion, thanks for your reply. My idea was to use the official MongoDB driver. That's why I asked the question. I already have the answer by using another library. – Israel Zinc Feb 08 '17 at 02:36