2015-08-23 1 views
0

Учитывая следующие orders коллекции (первые два порядка имеют один и тот же issuer) ...Как запустить Distinct команду с ReactiveMongo

{ "_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
  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"))) 
    ) 
    

    Он развивается в возмущаться выпусками.

  2. Или в вашем случае, почему бы просто не использовать нахождение с проекцией.

    Если я понимаю, что _id - это идентификатор заказа, так зачем идти на расстояние, если достаточно простого поиска.

+1

К сожалению, я использую старую версию ReactiveMongo, и приведенные выше утверждения не компилируются. Во всяком случае, моя команда возвращает '{" values ​​": [{" $ oid ":" 55d0f641a100000401b7e454 "}]," stats ": {" n ": 1," nscanned ": 1," nscannedObjects ": 1," timems " : 0, «cursor»: «BtreeCursor projectId_1»}, «ok»: 1.0} '... и является выражением' document.getAs [List [String]] («values») ', который на самом деле терпит неудачу, вероятно, потому, что он не находит подходящего писателя. – j3d

+0

Как насчет второго заявления? Вы всегда можете обновить :) – mavarazy

+0

Нет ... Мне нужно получить массив идентификаторов для динамического построения другого запроса ... – j3d