Как запустить команду Distinct с помощью ReactiveMongo
Учитывая следующее orders
Коллекция (первые два заказа имеют одинаковые issuer
)...
{ "_id" : ObjectId("55d9ab6391fc103256107f15"), "issuer": ObjectId("55d0f641a100000401b7e454"), "description": "one" }
{ "_id" : ObjectId("55d9ab6391fc103256107f16"), "issuer": ObjectId("55d0f641a100000401b7e454"), "description": "two" }
{ "_id" : ObjectId("55d9ab6391fc103256107f17"), "issuer": ObjectId("55d0f641a100000401b7e477"), "description": "three" }
... мне нужно получить List[String]
содержащий идентификаторы заказов, связанных с issuer
55d0f641a100000401b7e454, поэтому я определил Distinct
команда как это:
package object commands {
import reactivemongo.bson.{BSONString, BSONDocument}
import reactivemongo.core.commands.{CommandError, BSONCommandResultMaker, Command}
case class Distinct(
collectionName: String,
field: String,
query: Option[BSONDocument] = None
) extends Command[List[String]] {
override def makeDocuments = BSONDocument(
"distinct" -> BSONString(collectionName),
"key" -> field,
"query" -> query
)
val ResultMaker = Distinct
}
object Distinct extends BSONCommandResultMaker[List[String]] {
def apply(document: BSONDocument) = CommandError.checkOk(
document,
Some("distinct")
).toLeft(document.getAs[List[String]]("values").getOrElse(List.empty))
}
}
Наконец, я вызываю это так:
def distinct(collectionName: String, field: String, selector: BSONDocument): Future[List[String]] = {
ReactiveMongoPlugin.db.command(Distinct(
collectionName, field, Some(selector)
)).recover {
case e: LastError => throw DaoErrors.DatabaseError(collectionName, e)
}
}
...
val query = BSONDocument("issuer" -> BSONObjectID("55d0f641a100000401b7e454"))
distinct("orders", "_id", query).map { orderIds =>
// orderIds should contain the order ids... but it is empty
}
Проблема в том, что CommandError.checkOk.toLeft
в моем Distinct
объект всегда возвращается None
,
1 ответ
Вы можете использовать ReactiveMongo AggregationFramework, он должен выглядеть примерно так:
import play.modules.reactivemongo.json.commands.JSONAggregationFramework._ val query = Json.obj("issuer" -> Json.obj("$oid" -> "55d0f641a100000401b7e454")) collection.aggregate(Match(query), List(Group(JsNull)("fieldName" -> AddToSet("someField"))) )
Это развивалось в недавних выпусках.
Или в вашем случае, почему бы просто не использовать поиск с проекцией.
Если я понимаю, что _id - это идентификатор заказа, так зачем идти дальше, если простого поиска достаточно.