rewrite bookmark paginator with aggregation lookup

horsey-pieces
Thibault Duplessis 2021-02-07 12:34:13 +01:00
parent 864c507a0e
commit cd34138d6e
2 changed files with 33 additions and 23 deletions

View File

@ -40,7 +40,6 @@ final class BookmarkApi(
coll.delete.one($doc("g" $in gameIds)).void
def remove(gameId: Game.ID, userId: User.ID): Funit = coll.delete.one(selectId(gameId, userId)).void
// def remove(selector: Bdoc): Funit = coll.remove(selector).void
def toggle(gameId: Game.ID, userId: User.ID): Funit =
exists(gameId, userId) flatMap { e =>
@ -51,8 +50,7 @@ final class BookmarkApi(
def countByUser(user: User): Fu[Int] = coll.countSel(userIdQuery(user.id))
def gamePaginatorByUser(user: User, page: Int) =
paginator.byUser(user, page) dmap { _.mapResults(_.game) }
def gamePaginatorByUser(user: User, page: Int) = paginator.byUser(user, page)
private def add(gameId: Game.ID, userId: User.ID, date: DateTime): Funit =
coll.insert

View File

@ -1,7 +1,10 @@
package lila.bookmark
import reactivemongo.api.ReadPreference
import lila.common.paginator._
import lila.db.dsl._
import lila.game.Game
import lila.game.GameRepo
import lila.user.User
@ -11,35 +14,44 @@ final class PaginatorBuilder(
maxPerPage: lila.common.config.MaxPerPage
)(implicit ec: scala.concurrent.ExecutionContext) {
def byUser(user: User, page: Int): Fu[Paginator[Bookmark]] =
paginator(new UserAdapter(user), page)
private def paginator(adapter: AdapterLike[Bookmark], page: Int): Fu[Paginator[Bookmark]] =
def byUser(user: User, page: Int): Fu[Paginator[Game]] =
Paginator(
adapter,
new UserAdapter(user),
currentPage = page,
maxPerPage = maxPerPage
)
final class UserAdapter(user: User) extends AdapterLike[Bookmark] {
final class UserAdapter(user: User) extends AdapterLike[Game] {
def nbResults: Fu[Int] = coll countSel selector
def slice(offset: Int, length: Int): Fu[Seq[Bookmark]] =
for {
gameIds <-
coll
.find(selector, $doc("g" -> true).some)
.sort(sorting)
.skip(offset)
.cursor[Bdoc]()
.list(length) dmap { _ flatMap { _ string "g" } }
games <- gameRepo gamesFromSecondary gameIds
} yield games map { g =>
Bookmark(g, user)
}
def slice(offset: Int, length: Int): Fu[Seq[Game]] =
coll
.aggregateList(length, readPreference = ReadPreference.secondaryPreferred) { framework =>
import framework._
Match(selector) -> List(
Sort(Descending("d")),
Skip(offset),
Limit(length),
Project($doc("_id" -> false, "g" -> true)),
PipelineOperator(
$doc(
"$lookup" -> $doc(
"from" -> gameRepo.coll.name,
"as" -> "game",
"localField" -> "g",
"foreignField" -> "_id"
)
)
),
Unwind("game"),
ReplaceRootField("game")
)
}
.map {
_.flatMap(lila.game.BSONHandlers.gameBSONHandler.readOpt)
}
private def selector = $doc("u" -> user.id)
private def sorting = $sort desc "d"
}
}