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.