Skip to content

Commit

Permalink
Merge pull request #411 from viktortnk/distinct-command
Browse files Browse the repository at this point in the history
Implementation of 'Distinct' command
  • Loading branch information
cchantep committed Oct 11, 2015
2 parents 154437a + 0ba6052 commit 70e3e47
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 1 deletion.
Expand Up @@ -46,6 +46,10 @@ object BSONBatchCommands extends BatchCommands[BSONSerializationPack.type] {
implicit def CountWriter = BSONCountCommandImplicits.CountWriter
implicit def CountResultReader = BSONCountCommandImplicits.CountResultReader

val DistinctCommand = BSONDistinctCommand
implicit def DistinctWriter = BSONDistinctCommandImplicits.DistinctWriter
implicit def DistinctResultReader = BSONDistinctCommandImplicits.DistinctResultReader

val InsertCommand = BSONInsertCommand
implicit def InsertWriter = BSONInsertCommandImplicits.InsertWriter

Expand Down
15 changes: 14 additions & 1 deletion driver/src/main/scala/api/collections/genericcollection.scala
Expand Up @@ -51,14 +51,18 @@ trait GenericCollectionWithCommands[P <: SerializationPack with Singleton] { sel
}

trait BatchCommands[P <: SerializationPack] {
import reactivemongo.api.commands.{ AggregationFramework => AC, CountCommand => CC, InsertCommand => IC, UpdateCommand => UC, DeleteCommand => DC, DefaultWriteResult, LastError, ResolvedCollectionCommand, FindAndModifyCommand => FMC }
import reactivemongo.api.commands.{ AggregationFramework => AC, CountCommand => CC, DistinctCommand => DistC, InsertCommand => IC, UpdateCommand => UC, DeleteCommand => DC, DefaultWriteResult, LastError, ResolvedCollectionCommand, FindAndModifyCommand => FMC }

val pack: P

val CountCommand: CC[pack.type]
implicit def CountWriter: pack.Writer[ResolvedCollectionCommand[CountCommand.Count]]
implicit def CountResultReader: pack.Reader[CountCommand.CountResult]

val DistinctCommand: DistC[pack.type]
implicit def DistinctWriter: pack.Writer[ResolvedCollectionCommand[DistinctCommand.Distinct]]
implicit def DistinctResultReader: pack.Reader[DistinctCommand.DistinctResult]

val InsertCommand: IC[pack.type]
implicit def InsertWriter: pack.Writer[ResolvedCollectionCommand[InsertCommand.Insert]]

Expand Down Expand Up @@ -175,6 +179,15 @@ trait GenericCollection[P <: SerializationPack with Singleton] extends Collectio
*/
def count[H](selector: Option[pack.Document] = None, limit: Int = 0, skip: Int = 0, hint: Option[H] = None)(implicit h: H => CountCommand.Hint, ec: ExecutionContext): Future[Int] = runValueCommand(CountCommand.Count(query = selector, limit, skip, hint.map(h)))

/**
* Returns the distinct values for a specified field across a single collection and returns the results in an array.
* @param key the field for which to return distinct values
* @param selector the query selector that specifies the documents from which to retrieve the distinct values.
*/
def distinct(key: String, selector: Option[pack.Document] = None)(implicit ec: ExecutionContext): Future[List[pack.Value]] = {
runCommand(DistinctCommand.Distinct(keyString = key, query = selector)).map(_.values)
}

@inline private def defaultWriteConcern = db.connection.options.writeConcern

def bulkInsert(ordered: Boolean)(documents: ImplicitlyDocumentProducer*)(implicit ec: ExecutionContext): Future[MultiBulkWriteResult] =
Expand Down
27 changes: 27 additions & 0 deletions driver/src/main/scala/api/commands/bson/distinct.scala
@@ -0,0 +1,27 @@
package reactivemongo.api.commands.bson

import reactivemongo.api.BSONSerializationPack
import reactivemongo.api.commands._
import reactivemongo.bson._

object BSONDistinctCommand extends DistinctCommand[BSONSerializationPack.type] {
val pack = BSONSerializationPack
}

object BSONDistinctCommandImplicits {
import BSONDistinctCommand._

implicit object DistinctWriter extends BSONDocumentWriter[ResolvedCollectionCommand[Distinct]] {
def write(distinct: ResolvedCollectionCommand[Distinct]): BSONDocument =
BSONDocument(
"distinct" -> distinct.collection,
"key" -> distinct.command.keyString,
"query" -> distinct.command.query)
}

implicit object DistinctResultReader extends DealingWithGenericCommandErrorsReader[DistinctResult] {
def readResult(doc: BSONDocument): DistinctResult =
DistinctResult(doc.getAs[BSONArray]("values").fold[List[BSONValue]](List())(_.values.toList))

}
}
12 changes: 12 additions & 0 deletions driver/src/main/scala/api/commands/distinct.scala
@@ -0,0 +1,12 @@
package reactivemongo.api.commands

import reactivemongo.api.SerializationPack

trait DistinctCommand[P <: SerializationPack] extends ImplicitCommandHelpers[P] {
case class Distinct(
//{ distinct: <collection>, key: <key>, query: <query> }
keyString: String,
query: Option[pack.Document]) extends CollectionCommand with CommandWithPack[pack.type] with CommandWithResult[DistinctResult]

case class DistinctResult(values: List[pack.Value])
}
5 changes: 5 additions & 0 deletions driver/src/test/scala/AggregationSpec.scala
Expand Up @@ -107,5 +107,10 @@ object AggregationSpec extends org.specs2.mutable.Specification {
map(_.documents) aka "results" must beEqualTo(expected).
await(timeoutMillis)
}

"return distinct states" in {
val expected: List[BSONValue] = List("NY", "FR", "JP").map(BSONString.apply)
collection.distinct("state").aka("results") must beEqualTo(expected).await(timeoutMillis)
}
}
}

0 comments on commit 70e3e47

Please sign in to comment.