Mongoldb-Casbah: получить первый матч в коллекции

Я использую Scala и Mongoldb-Casbah, и я получаю некоторые данные с:

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

Возвращенные данные являются коллекцией, подобной этой:

[{_id: "...", цены:[ {myValue:"...",...}, {myValue:"...",...},... ] }, {... },... ]

Что мне нужно получить, это первое не пустое myValue,

Я пробовал разные вещи, как:

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

но это не возвращает одно единственное значение, если я не сделаю это еще более сложным. Я не пробовал findMap или же collectFirst пока что

Любая идея, как извлечь один myValue по этим данным?

1 ответ

Например, если у вас есть документы, как показано ниже:

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

Если вы хотите извлечь один myValue элемент, который не является пустым, вы можете использовать оператор проекции $ elemMatch. $elemMatch оператор ограничивает содержимое поля массива из результатов запроса, чтобы он содержал только первый элемент, соответствующий $elemMatch состояние.

В качестве примера, чтобы сделать это в 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} ] }

Выше был протестирован с: MongoDB v3.2, Scala v2.11.7, Casbah v3.1.0.

Другие вопросы по тегам