0

I am using Scala and Mongoldb-Casbah and I get some data with:

val myData: Traversable[Imports.DBObject] = myCollection.find(query).toTraversable

The data returned are a collection like this:

[ { _id:"...", prices:[ {myValue:"...",...}, {myValue:"...",...},... ] }, {... },... ]

What I need to get, it is the first not empty myValue.

I tried different things like:

myData.foldLeft(List[Any]()) { (acc, v) =>
      acc ++ v.get("prices").asInstanceOf[BasicDBList].filter(_.asInstanceOf[DBObject].getOrElse("myValue", "").toString.nonEmpty).take(1)
    }

but it is not returning one single value unless I make it even more complicated. I didn't tried findMap or collectFirst yet tho.

Any idea how to extract one single myValue from that data?

Randomize
  • 8,651
  • 18
  • 78
  • 133

1 Answers1

0

For example, if you have documents like below:

{
  "_id": ObjectId(...),
  "item": "A",
  "prices": [ {},{"myValue": 1}, {"myValue": 4}, {} ]
},
{
  "_id": ObjectId(...),
  "item": "B",
  "prices": [ {"myValue": 7}, {}, {"myValue": 9}, {} ]
}

If you would like to extract one single myValue element that is not empty, you could utilise $elemMatch projection operator. The $elemMatch operator limits the contents of an array field from the query results to contain only the first element matching the $elemMatch condition.

As an example to do this in scala/casbah:

val coll = MongoClient()("dbName")("collName")

/*  The query below is equivalent to db mongo shell 
    db.collName.find({item:"A"}, {prices: { $elemMatch: { myValue: {$exists:true} } } } ) */

val elemMatch = "prices" $elemMatch MongoDBObject("myValue"-> MongoDBObject("$exists" -> true))
val query = MongoDBObject("item" -> "A")

coll.find(query, elemMatch).foreach { doc =>
    println(doc)
}
// Output: { "_id" : { "$oid" : "..."} , "prices" : [ { "myValue" : 1.0} ] }

The above was tested with : MongoDB v3.2, Scala v2.11.7, Casbah v3.1.0.

Wan B.
  • 18,367
  • 4
  • 54
  • 71