scalamongodbintellij-ideacasbah

Mongo $elemMatch in Casbah


I'm using Casbah 2.9.2

My mongodb schema looks like:

[ _id : "Triangle", Info : [ Color : "Red", Line : "Thin", UseID : "1", SourceId : "2" ] ]

I want to be able to write an update line that first checks if _id, Color and Line are together unique, if so update the UseID and SourceID otherwise create a new "Info" entry. This gets me exactly what I want from the command line:

db.shapes.update( { _id : 'Triangle', Info : { $not : { $elemMatch : { Color : 'Red', Line : 'Thick' } } } }, { $push : { Info : { Color : 'Red', Line : 'Thick', UseID : '2', SourceId : '3' } } }, true)

Giving me this entry:

[ _id : "Triangle", Info : [ { Color : "Red", Line : "Thin", UseID : "1", SourceId : "2" }, { Color : "Red", Line : "Thick", UseID : "2", SourceId : "3" } ] ]

However when I translate to Casbah for Scala it does not:

shapesCollection.update( { "_id" -> shape, "Info" $not { _ $elemMatch { "Color" -> color, "Line" -> line } } }, { $push -> { "Info" -> { "Color" -> color, "Line" -> line, "UseId" -> useId, "SourceId" -> srcId } } }, true )

The first complaint (from IntelliJ) is it wants all of the ','s to be ';'s which I feel is not correct, but in order to debug I oblige, which takes me to the second error saying:

"error: No Implicit view available from (java.lang.String, java.lang.String) => com.mongodb.casbah.query.Imports.DBObject. Error occurred in an application involving default arguments. "Info" $not { _ $elemMatch {"

So I guess the questions are, Can I even do the update I'm doing from the command line in Casbah? If so, how?

Thanks!


Solution

  • So for anyone that cares, first my update string was a little off, it would throw errors if the "Color" and "Line" didn't exist but the "_id" did. Basically it looks like $push with upsetter as true doesn't add to an existing "_id", so I was getting duplicate key errors as it tried to add the entry. But, that's moot, the real solution to what I wanted to do was to not use Casbah and instead use the MongoDB Java Driver. I was then able to get $elemMatch to do what I wanted.

    Also this was probably part of my problem, since I went a different route I didn't get a chance to test it:

    "If you really feel the need to use ++ with a mix of DSL and bare matches, we provide additive support for -> Tuple pairs. You should make the query operator calls first:"

    val qMix = ("baz" -> 5) ++ ("foo" $gte 5) ++ ("x" -> "y")
    /* error: value ++ is not a member of (java.lang.String, Int)
       val qMix = ("baz" -> 5) ++ ("foo" $gte 5) ++ ("x" -> "y") */
    

    The operator is chained against the result of DSL operators (which incidentally properly return a DBObject):

    val qMix = ("foo" $gte 5) ++ ("baz" -> 5) ++ ("x" -> "y")
    /* qMix: com.mongodb.casbah.commons.Imports.DBObject =
       { "foo" : { "$gte" : 5} , "baz" : 5 , "x" : "y"} */
    

    From: http://api.mongodb.org/scala/casbah/current/tutorial.html