2013-03-13 15:41:43 -06:00
|
|
|
package lila.db
|
|
|
|
package paginator
|
|
|
|
|
2016-04-01 05:41:57 -06:00
|
|
|
import dsl._
|
2016-03-02 06:13:36 -07:00
|
|
|
import reactivemongo.api._
|
2019-11-29 11:08:13 -07:00
|
|
|
import reactivemongo.api.bson._
|
2020-02-27 10:18:15 -07:00
|
|
|
import scala.util.chaining._
|
2013-03-13 15:41:43 -06:00
|
|
|
|
2013-05-24 11:04:49 -06:00
|
|
|
import lila.common.paginator.AdapterLike
|
|
|
|
|
2013-03-25 11:28:31 -06:00
|
|
|
final class CachedAdapter[A](
|
|
|
|
adapter: AdapterLike[A],
|
2017-02-14 08:34:07 -07:00
|
|
|
val nbResults: Fu[Int]
|
2019-12-13 18:17:43 -07:00
|
|
|
)(implicit ec: scala.concurrent.ExecutionContext)
|
|
|
|
extends AdapterLike[A] {
|
2013-03-13 15:41:43 -06:00
|
|
|
|
2013-03-26 10:31:18 -06:00
|
|
|
def slice(offset: Int, length: Int): Fu[Seq[A]] =
|
2013-03-25 11:28:31 -06:00
|
|
|
adapter.slice(offset, length)
|
2013-03-13 15:41:43 -06:00
|
|
|
}
|
2014-07-03 12:57:37 -06:00
|
|
|
|
2016-04-01 10:43:50 -06:00
|
|
|
final class Adapter[A: BSONDocumentReader](
|
2018-11-27 20:03:03 -07:00
|
|
|
collection: Coll,
|
|
|
|
selector: Bdoc,
|
2019-11-29 15:11:03 -07:00
|
|
|
projection: Option[Bdoc],
|
2018-11-27 20:03:03 -07:00
|
|
|
sort: Bdoc,
|
2020-02-27 10:18:15 -07:00
|
|
|
readPreference: ReadPreference = ReadPreference.primary,
|
|
|
|
hint: Option[Bdoc] = None
|
2019-12-13 18:17:43 -07:00
|
|
|
)(implicit ec: scala.concurrent.ExecutionContext)
|
|
|
|
extends AdapterLike[A] {
|
2014-07-03 12:57:37 -06:00
|
|
|
|
2019-11-29 15:11:03 -07:00
|
|
|
def nbResults: Fu[Int] = collection.secondaryPreferred.countSel(selector)
|
2014-07-03 12:57:37 -06:00
|
|
|
|
2017-03-25 04:49:39 -06:00
|
|
|
def slice(offset: Int, length: Int): Fu[List[A]] =
|
2019-12-13 07:30:20 -07:00
|
|
|
collection
|
|
|
|
.find(selector, projection)
|
2014-07-03 12:57:37 -06:00
|
|
|
.sort(sort)
|
2016-04-01 10:43:50 -06:00
|
|
|
.skip(offset)
|
2020-02-27 10:18:15 -07:00
|
|
|
.pipe { query =>
|
|
|
|
hint match {
|
|
|
|
case None => query
|
2020-07-19 07:11:06 -06:00
|
|
|
case Some(h) => query.hint(collection hint h)
|
2020-02-27 10:18:15 -07:00
|
|
|
}
|
|
|
|
}
|
2020-07-19 07:11:06 -06:00
|
|
|
.cursor[A](readPreference)
|
|
|
|
.list(length)
|
2018-11-27 20:03:03 -07:00
|
|
|
}
|
|
|
|
|
2018-11-27 20:51:12 -07:00
|
|
|
/*
|
2019-09-20 08:47:23 -06:00
|
|
|
* because mongodb mapReduce doesn't support `skip`, slice requires two queries.
|
2018-11-27 20:51:12 -07:00
|
|
|
* The first one gets the IDs with `skip`.
|
|
|
|
* The second one runs the mapReduce on these IDs.
|
|
|
|
* This avoid running mapReduce on many unnecessary docs.
|
|
|
|
* NOTE: Requires string ID.
|
|
|
|
*/
|
2018-11-27 20:03:03 -07:00
|
|
|
final class MapReduceAdapter[A: BSONDocumentReader](
|
|
|
|
collection: Coll,
|
|
|
|
selector: Bdoc,
|
2018-11-27 20:51:12 -07:00
|
|
|
sort: Bdoc,
|
2018-11-27 20:03:03 -07:00
|
|
|
runCommand: RunCommand,
|
2018-11-27 20:51:12 -07:00
|
|
|
command: Bdoc,
|
2018-11-27 20:03:03 -07:00
|
|
|
readPreference: ReadPreference = ReadPreference.primary
|
2019-12-13 18:17:43 -07:00
|
|
|
)(implicit ec: scala.concurrent.ExecutionContext)
|
|
|
|
extends AdapterLike[A] {
|
2018-11-27 20:03:03 -07:00
|
|
|
|
2019-11-29 15:11:03 -07:00
|
|
|
def nbResults: Fu[Int] = collection.secondaryPreferred.countSel(selector)
|
2018-11-27 20:03:03 -07:00
|
|
|
|
|
|
|
def slice(offset: Int, length: Int): Fu[List[A]] =
|
2019-12-13 07:30:20 -07:00
|
|
|
collection
|
|
|
|
.find(selector, $id(true).some)
|
2018-11-27 20:51:12 -07:00
|
|
|
.sort(sort)
|
|
|
|
.skip(offset)
|
2020-07-19 07:11:06 -06:00
|
|
|
.cursor[Bdoc](readPreference)
|
|
|
|
.list(length)
|
2019-11-29 11:08:13 -07:00
|
|
|
.dmap { _ flatMap { _.getAsOpt[BSONString]("_id") } }
|
2018-11-27 20:51:12 -07:00
|
|
|
.flatMap { ids =>
|
|
|
|
runCommand(
|
|
|
|
$doc(
|
|
|
|
"mapreduce" -> collection.name,
|
2019-12-13 07:30:20 -07:00
|
|
|
"query" -> $inIds(ids),
|
|
|
|
"sort" -> sort,
|
|
|
|
"out" -> $doc("inline" -> true)
|
2018-11-27 20:51:12 -07:00
|
|
|
) ++ command,
|
|
|
|
readPreference
|
|
|
|
) map { res =>
|
2019-12-13 07:30:20 -07:00
|
|
|
res.getAsOpt[List[Bdoc]]("results").??(_ flatMap implicitly[BSONDocumentReader[A]].readOpt)
|
|
|
|
}
|
2018-11-27 20:03:03 -07:00
|
|
|
}
|
|
|
|
}
|