Reputation: 2141
I have a user object as follows:
{ user: "joe", acks: ["a", "b" ] }
I want to add a set of strings to the acks field. Here's my attempt to do this with one update:
def addSomeAcks(toBeAcked = Array[String])
DB.getCollection("userAcks").update(
MongoDBObject("user" -> "joe"),
$addToSet("acks") $each toBeAcked
)
}
def test() {
addSomeAcks(Set("x", "y", "z"))
}
When I run this code I get an embedded set as follows:
{ user: "joe", acks: ["a", "b", ["x", "y", "z" ] ] }
but the result I want is:
{ user: "joe", acks: ["a", "b", "x", "y", "z" ] }
I can make it work by calling update for each item in toBeAcked
, is there a way to do this in one call?
Upvotes: 1
Views: 285
Reputation: 16422
The problem is that $each
takes a variable number of arguments, not a collection type like Traversable
. Because of that it treats the set that you pass as a single element and adds it to array as such. This leads to nesting as you observe. You need to unwrap it this way: $each(toBeAcked: _*)
or pass each elem separately $each("x", "y", "z")
.
Here is a complete example that works as you'd expect it to:
package com.example
import com.mongodb.casbah.Imports._
object TestApp extends App {
val col = MongoConnection()("test")("userAcks")
def printAll(): Unit =
col.find().foreach(println)
def insertFirst(): Unit =
col.insert(MongoDBObject("user" -> "joe", "acks" -> List("a", "b")))
def addSomeAcks(toBeAcked: Seq[String]): Unit =
col.update(
MongoDBObject("user" -> "joe"),
$addToSet("acks") $each (toBeAcked: _*))
printAll()
insertFirst()
printAll()
addSomeAcks(Seq("x", "y", "z"))
printAll()
}
Upvotes: 5