new search

pull/1390/head
Thibault Duplessis 2016-01-07 13:14:46 +07:00
parent 9bb640ba08
commit 02d8487f96
4 changed files with 31 additions and 45 deletions

View File

@ -34,15 +34,15 @@ final class ForumSearchApi(
Fields.date -> view.post.createdAt.getDate)
def reset = client match {
case c: ESClientHttp => c.createTempIndex flatMap { temp =>
loginfo(s"Index to ${temp.tempIndex.name}")
case c: ESClientHttp => c.putMapping >> {
loginfo(s"Index to ${c.index.name}")
import lila.db.api._
import lila.forum.tube.postTube
$enumerate.bulk[Option[Post]]($query[Post](Json.obj()), 500) { postOptions =>
(postApi liteViews postOptions.flatten) flatMap { views =>
temp.storeBulk(views map (v => Id(v.post.id) -> toDoc(v)))
c.storeBulk(views map (v => Id(v.post.id) -> toDoc(v)))
}
} >> temp.aliasBackToMain
}
}
case _ => funit
}

View File

@ -10,6 +10,8 @@ import play.api.libs.json._
final class GameSearchApi(client: ESClient) extends SearchReadApi[Game, Query] {
private var writeable = true
def search(query: Query, from: From, size: Size) =
client.search(query, from, size) flatMap { res =>
import lila.db.api.$find
@ -23,13 +25,13 @@ final class GameSearchApi(client: ESClient) extends SearchReadApi[Game, Query] {
def ids(query: Query, max: Int): Fu[List[String]] =
client.search(query, From(0), Size(max)).map(_.ids)
def store(game: Game) = storable(game) ?? {
def store(game: Game) = (writeable && storable(game)) ?? {
GameRepo isAnalysed game.id flatMap { analysed =>
client.store(Id(game.id), toDoc(game, analysed))
}
}
private def storable(game: Game) = (game.finished || game.imported) && game.playedTurns > 4
private def storable(game: Game) = (game.finished || game.imported)
private def toDoc(game: Game, analysed: Boolean) = Json.obj(
Fields.status -> (game.status match {
@ -55,22 +57,25 @@ final class GameSearchApi(client: ESClient) extends SearchReadApi[Game, Query] {
).noNull
def reset(max: Option[Int]): Funit = client match {
case c: ESClientHttp => c.createTempIndex flatMap { temp =>
loginfo(s"Index to ${temp.tempIndex.name}")
case c: ESClientHttp =>
loginfo(s"Index to ${c.index.name}")
val resetStartAt = DateTime.now
val resetStartSeconds = nowSeconds
writeable = false
Thread sleep 3000
for {
_ <- doIndex(temp, Json.obj(), max)
_ <- c.putMapping
_ <- doIndex(c, Json.obj(), max)
_ = loginfo("[game search] Complete indexation in %ss".format(nowSeconds - resetStartSeconds))
_ <- doIndex(temp, lila.game.Query createdSince resetStartAt.minusHours(3), max)
_ <- doIndex(c, lila.game.Query createdSince resetStartAt.minusHours(3), max)
_ = loginfo("[game search] Complete indexation in %ss".format(nowSeconds - resetStartSeconds))
_ <- temp.aliasBackToMain
} yield ()
}
} yield {
writeable = true
}
case _ => funit
}
private def doIndex(temp: ESClientHttpTemp, selector: JsObject, max: Option[Int]): Funit = {
private def doIndex(client: ESClientHttp, selector: JsObject, max: Option[Int]): Funit = {
import lila.db.api._
import lila.game.tube.gameTube
var nb = 0
@ -84,7 +89,7 @@ final class GameSearchApi(client: ESClient) extends SearchReadApi[Game, Query] {
val games = gameOptions.flatten filter storable
val nbGames = games.size
(GameRepo filterAnalysed games.map(_.id).toSeq flatMap { analysedIds =>
temp.storeBulk(games map { g =>
client.storeBulk(games map { g =>
Id(g.id) -> toDoc(g, analysedIds(g.id))
}).logFailure("game bulk")
}) >>- {

View File

@ -37,13 +37,13 @@ final class ESClientHttp(
def deleteByIds(ids: List[lila.search.Id]) = writeable ??
HTTP(s"delete/ids/${index.name}", Json.obj("ids" -> ids.map(_.value)))
def createTempIndex = {
val tempIndex = Index(s"${index.name}_${ornicar.scalalib.Random.nextString(4)}")
val tempClient = new ESClientHttpTemp(
index,
new ESClientHttp(endpoint, tempIndex, writeable))
tempClient.putMapping inject tempClient
}
def putMapping =
HTTP(s"mapping/${index.name}/${index.name}", Json.obj())
def storeBulk(docs: Seq[(Id, JsObject)]) =
HTTP(s"store/bulk/${index.name}/${index.name}", JsObject(docs map {
case (Id(id), doc) => id -> JsString(Json.stringify(doc))
}))
private[search] def HTTP[D: Writes, R](url: String, data: D, read: String => R): Fu[R] =
WS.url(s"$endpoint/$url").post(Json toJson data) flatMap {
@ -55,25 +55,6 @@ final class ESClientHttp(
private val logger = play.api.Logger("ESClientHttp")
}
final class ESClientHttpTemp(
mainIndex: Index,
client: ESClientHttp) {
def putMapping =
client.HTTP(s"mapping/${tempIndex.name}/${mainIndex.name}", Json.obj())
def tempIndex = client.index
def storeBulk(docs: Seq[(Id, JsObject)]) =
client.HTTP(s"store/bulk/${tempIndex.name}/${mainIndex.name}", JsObject(docs map {
case (Id(id), doc) => id -> JsString(Json.stringify(doc))
}))
def aliasBackToMain =
client.HTTP(s"alias/${tempIndex.name}/${mainIndex.name}", Json.obj())
}
final class ESClientStub extends ESClient {
def search[Q: Writes](query: Q, from: From, size: Size) = fuccess(SearchResponse(Nil))
def count[Q: Writes](query: Q) = fuccess(CountResponse(0))

View File

@ -26,13 +26,13 @@ final class TeamSearchApi(
Fields.nbMembers -> team.nbMembers)
def reset = client match {
case c: ESClientHttp => c.createTempIndex flatMap { temp =>
loginfo(s"Index to ${temp.tempIndex.name}")
case c: ESClientHttp => c.putMapping >> {
loginfo(s"Index to ${c.index.name}")
import lila.db.api._
import lila.team.tube.teamTube
$enumerate.bulk[Option[Team]]($query[Team](Json.obj("enabled" -> true)), 300) { teamOptions =>
temp.storeBulk(teamOptions.flatten map (t => Id(t.id) -> toDoc(t)))
} >> temp.aliasBackToMain
c.storeBulk(teamOptions.flatten map (t => Id(t.id) -> toDoc(t)))
}
}
case _ => funit
}