Search code examples
mongodbcasbah

Casbah - parametric find or findOne do not return what is there


I have the problem exactly as it is described in the title.

For example, if I try:

  val key = "myKey"
  val value = "myVal"

  val one = Option(collection.findOne(MongoDBObject(key -> value)))
  val all = collection.find(MongoDBObject(key -> value))

then I check the contents and:

  println(one)        =>    None
  println(all.size)   =>    0

however, if I do not use the MongoDBObject parameter, it works - it finds all the stuff that is there.

What am I doing wrong? I assume that the parameter object specifies a key-value criteria that should make the search return only results that contain those key-value pairs...

And I have to say that the key and the value are valid. The value, however, is numeric, but in it is stringified for these statements, so should be no problem. Or not?

UPDATE:

While trying to capture the data necessary for more precised description of the problem, I have run tests sufficient to realize the origin of the problem. It turns out that Casbah does not leave "1" to remain a String, it automatically casts it into an Integer, and thus, comparing a String with an Integer, surely never returns true. Ok, so I can think of solving the problem like this:

def getObjectBy(key: String, value: String) = {
  val all = collection.find()
  val buffer = Buffer[DBObject]()
  while(all.hasNext) { buffer += all.next }
  val haveTheKey = buffer.filter(_.keySet.contains(key))

  if(haveTheKey.size > 0) {
    val one = haveTheKey(0)
    val v = one.get(key)

    // 1st way (hell)
    v match {
      case i: Int => if(i == value.toInt) Some(one)
      case s: String => if(s == value) Some(one)
      case f: Float => if(s == value.toFloat) Some(one)
      //... and so on..
      case _ => None
    }

    // 2nd way (better?)
    if(v.toString == value) Some(one) else None

  } else None

}

but that is rediculous... I suppose, that I just don't get something here, please tell me, what am I missing?


Solution

  • Ok, finally I came up with some sort of a solution. In my situation, values can only be either decendants of AnyVal or the very java.lang.String. So the common parent would be Any. That is why I have changed the passed value type to Any:

    def getObjectBy(key: String, value: Any) = {
      // ...
    }
    

    and it worked indeed! Doh, it was so easy! I never used Object in Java or Any in Scala, and did not think that it would work like that... but..