more insights fixes
parent
f3ef586de0
commit
f764deb946
|
@ -148,7 +148,10 @@ final private class AggregationPipeline(store: Storage)(implicit ec: scala.concu
|
||||||
def matchMoves(extraMatcher: Bdoc = $empty) =
|
def matchMoves(extraMatcher: Bdoc = $empty) =
|
||||||
combineDocs(extraMatcher :: question.filters.collect {
|
combineDocs(extraMatcher :: question.filters.collect {
|
||||||
case f if f.dimension.isInMove => f.matcher
|
case f if f.dimension.isInMove => f.matcher
|
||||||
}).some.filterNot(_.isEmpty) map Match
|
} ::: (dimension match {
|
||||||
|
case D.TimeVariance => List($doc(F.moves("v") $exists true))
|
||||||
|
case _ => Nil
|
||||||
|
})).some.filterNot(_.isEmpty) map Match
|
||||||
def projectForMove =
|
def projectForMove =
|
||||||
Project(BSONDocument({
|
Project(BSONDocument({
|
||||||
metric.dbKey :: dimension.dbKey :: filters.collect {
|
metric.dbKey :: dimension.dbKey :: filters.collect {
|
||||||
|
@ -188,7 +191,7 @@ final private class AggregationPipeline(store: Storage)(implicit ec: scala.concu
|
||||||
List(
|
List(
|
||||||
projectForMove,
|
projectForMove,
|
||||||
unwindMoves,
|
unwindMoves,
|
||||||
matchMoves($doc(F.moves("o") -> $doc("$exists" -> true))),
|
matchMoves($doc(F.moves("o") $exists true)),
|
||||||
sampleMoves
|
sampleMoves
|
||||||
) :::
|
) :::
|
||||||
group(dimension, GroupFunction("$push", $doc("$cond" -> $arr("$" + F.moves("o"), 1, 0)))) :::
|
group(dimension, GroupFunction("$push", $doc("$cond" -> $arr("$" + F.moves("o"), 1, 0)))) :::
|
||||||
|
@ -267,7 +270,7 @@ final private class AggregationPipeline(store: Storage)(implicit ec: scala.concu
|
||||||
List(
|
List(
|
||||||
projectForMove,
|
projectForMove,
|
||||||
unwindMoves,
|
unwindMoves,
|
||||||
matchMoves(),
|
matchMoves($doc(F.moves("v") $exists true)),
|
||||||
sampleMoves
|
sampleMoves
|
||||||
) :::
|
) :::
|
||||||
group(
|
group(
|
||||||
|
|
|
@ -83,16 +83,18 @@ final private class Indexer(
|
||||||
} map (_.toOption)
|
} map (_.toOption)
|
||||||
}
|
}
|
||||||
val query = gameQuery(user) ++ $doc(Game.BSONFields.createdAt $gte from)
|
val query = gameQuery(user) ++ $doc(Game.BSONFields.createdAt $gte from)
|
||||||
|
val bulkInsert = 50
|
||||||
|
val perSecond = 800
|
||||||
gameRepo
|
gameRepo
|
||||||
.sortedCursor(query, Query.sortChronological)
|
.sortedCursor(query, Query.sortChronological)
|
||||||
.documentSource()
|
.documentSource()
|
||||||
.take(maxGames)
|
.take(maxGames)
|
||||||
.mapAsync(16)(toEntry)
|
.mapAsync(16)(toEntry)
|
||||||
.via(LilaStream.collect)
|
.via(LilaStream.collect)
|
||||||
.throttle(800, 1 second)
|
|
||||||
.zipWithIndex
|
.zipWithIndex
|
||||||
.map { case (e, i) => e.copy(number = fromNumber + i.toInt) }
|
.map { case (e, i) => e.copy(number = fromNumber + i.toInt) }
|
||||||
.grouped(50)
|
.grouped(bulkInsert)
|
||||||
|
.throttle(perSecond / bulkInsert, 1 second)
|
||||||
.map(storage.bulkInsert)
|
.map(storage.bulkInsert)
|
||||||
.toMat(Sink.ignore)(Keep.right)
|
.toMat(Sink.ignore)(Keep.right)
|
||||||
.run
|
.run
|
||||||
|
|
|
@ -101,8 +101,12 @@ final private class PovToEntry(
|
||||||
case (e, i) if (i % 2) == pivot => e
|
case (e, i) if (i % 2) == pivot => e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val blurs = {
|
||||||
|
val bools = from.pov.player.blurs.booleans
|
||||||
|
bools ++ Array.fill(movetimes.size - bools.size)(false)
|
||||||
|
}
|
||||||
val timeCvs = slidingMoveTimesCvs(movetimes)
|
val timeCvs = slidingMoveTimesCvs(movetimes)
|
||||||
movetimes.zip(roles).zip(boards).zip(from.pov.player.blurs.booleans).zip(timeCvs).zipWithIndex.map {
|
movetimes.zip(roles).zip(boards).zip(blurs).zip(timeCvs).zipWithIndex.map {
|
||||||
case movetime ~ role ~ board ~ blur ~ timeCv ~ i =>
|
case movetime ~ role ~ board ~ blur ~ timeCv ~ i =>
|
||||||
val ply = i * 2 + from.pov.color.fold(1, 2)
|
val ply = i * 2 + from.pov.color.fold(1, 2)
|
||||||
val prevInfo = prevInfos lift i
|
val prevInfo = prevInfos lift i
|
||||||
|
@ -133,18 +137,28 @@ final private class PovToEntry(
|
||||||
opportunism = opportunism,
|
opportunism = opportunism,
|
||||||
luck = luck,
|
luck = luck,
|
||||||
blur = blur,
|
blur = blur,
|
||||||
timeCv = timeCv.some
|
timeCv = timeCv
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def slidingMoveTimesCvs(movetimes: Seq[Centis]): Iterator[Float] =
|
private def slidingMoveTimesCvs(movetimes: Seq[Centis]): Seq[Option[Float]] = {
|
||||||
movetimes.iterator
|
val sliding = 13 // should be odd
|
||||||
.sliding(14)
|
val nb = movetimes.size
|
||||||
.map(a => a.toList.sorted.drop(1).dropRight(1))
|
if (nb < sliding) Vector.fill(nb)(none[Float])
|
||||||
.flatMap(a => coefVariation(a.map(_.centis + 10)))
|
else {
|
||||||
|
val sides = Vector.fill(sliding / 2)(none[Float])
|
||||||
|
val cvs = movetimes
|
||||||
|
.sliding(sliding)
|
||||||
|
.map { a =>
|
||||||
|
// drop outliers
|
||||||
|
coefVariation(a.map(_.centis + 10).toSeq.sorted.drop(1).dropRight(1))
|
||||||
|
}
|
||||||
|
sides ++ cvs ++ sides
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private def coefVariation(a: List[Int]): Option[Float] = {
|
private def coefVariation(a: Seq[Int]): Option[Float] = {
|
||||||
val s = Stats(a)
|
val s = Stats(a)
|
||||||
s.stdDev.map { _ / s.mean }
|
s.stdDev.map { _ / s.mean }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue