如何使用ReactiveMongo运行Distinct命令

时间:2015-08-23 12:39:51

标签: mongodb scala 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相关联的订单的ID,因此我已经定义了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 个答案:

答案 0 :(得分:2)

  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. 或者在您的情况下,为什么不使用find with projection。

    如果我理解_id是订单ID,那么为什么要走远,如果简单的查找就足够了。