Skip to content

Commit

Permalink
Merge pull request #111 from opentargets/rm-target-filter-pub-bydate
Browse files Browse the repository at this point in the history
Filter biobliography results by publication date
  • Loading branch information
remo87 authored May 27, 2022
2 parents 340831e + cbb423a commit 4dd26f5
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 8 deletions.
65 changes: 63 additions & 2 deletions app/models/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import play.api.libs.json._
import play.api.{Configuration, Environment, Logging}
import play.db.NamedDatabase

import java.text.SimpleDateFormat
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import scala.collection.immutable.ArraySeq
import scala.concurrent._

Expand Down Expand Up @@ -757,32 +760,90 @@ class Backend @Inject() (implicit
def getLiteratureOcurrences(ids: Set[String], cursor: Option[String]): Future[Publications] = {
import Pagination._

getLiterature(ids, Option.empty, Option.empty, Option.empty, cursor)
}

def getLiteratureOcurrences(ids: Set[String],
year: Option[Int],
month: Option[Int],
dateComparator: Option[ComparatorEnum.Comparator],
cursor: Option[String]
): Future[Publications] = {
import Pagination._

getLiterature(ids, year, month, dateComparator, cursor)
}

private def getLiterature(ids: Set[String],
year: Option[Int],
month: Option[Int],
dateComparator: Option[ComparatorEnum.Comparator],
cursor: Option[String]
) = {
val table = defaultOTSettings.clickhouse.literature
val indexTable = defaultOTSettings.clickhouse.literatureIndex
logger.info(s"query literature ocurrences in table ${table.name}")

val pag = Helpers.Cursor.to(cursor).flatMap(_.asOpt[Pagination]).getOrElse(Pagination.mkDefault)

val simQ = QLITAGG(table.name, indexTable.name, ids, pag.size, pag.offset)

def getResultToMap(v: Vector[Publication]) =
year match {
case Some(value) =>
v.filter(pub =>
filterLiteratureByDate(
pub,
(year.get, month.getOrElse(1), dateComparator.getOrElse(ComparatorEnum.GreaterThan))
)
)
case None => v
}

dbRetriever.executeQuery[Long, Query](simQ.total).flatMap {
case Vector(total) if total > 0 =>
logger.debug(s"total number of publication occurrences $total")
dbRetriever.executeQuery[Publication, Query](simQ.query).map { v =>
val pubs = v.map(pub => Json.toJson(pub))
val result = getResultToMap(v)
val pubs = result
.map(pub => Json.toJson(pub))
val nCursor = if (v.size < pag.size) {
None
} else {
val npag = pag.next
Helpers.Cursor.from(Some(Json.toJson(npag)))
}
Publications(total, nCursor, pubs)
Publications(pubs.size, nCursor, pubs)
}
case _ =>
logger.info(s"there is no publications with this set of ids $ids")
Future.successful(Publications.empty())
}
}

def filterLiteratureByDate(pub: Publication,
dateAndComparator: (Int, Int, ComparatorEnum.Comparator)
): Boolean = {
//if no year is sent no filter is applied

def compareDates(pubDate: LocalDate, reqDate: LocalDate): Boolean =
dateAndComparator._3 match {
case ComparatorEnum.GreaterThan => pubDate.compareTo(reqDate) >= 0
case ComparatorEnum.LesserThan => pubDate.compareTo(reqDate) <= 0
}

def getPubDate(year: Int, month: Int) = {
val pubDate = LocalDate.of(pub.year, pub.month, 1)
val reqDate = LocalDate.of(year, month, 1)
(pubDate, reqDate)
}

val (pubDate: LocalDate, reqDate: LocalDate) =
getPubDate(dateAndComparator._1, dateAndComparator._2)
compareDates(pubDate, reqDate)

}

/** @param index key of index (name field) in application.conf
* @param default fallback index name
* @return elasticsearch index name resolved from application.conf or default.
Expand Down
4 changes: 2 additions & 2 deletions app/models/db/QLITAGG.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ case class QLITAGG(
)

val litQ: Q = Q(
Select(pmid :: pmcid :: date :: sentences :: Nil),
Select(pmid :: pmcid :: date :: year :: month :: sentences :: Nil),
From(T),
PreWhere(F.in(pmid, pmidsQ(pmid :: Nil).toColumn(None)))
)
Expand All @@ -64,7 +64,7 @@ case class QLITAGG(

override val query: Q = {
val q = Q(
Select(pmid :: pmcid :: date :: sentences :: Nil),
Select(pmid :: pmcid :: date :: year :: month :: sentences :: Nil),
From(pmidsQ(pmid :: Nil).toColumn(None), Some("L")),
Join(litQ.toColumn(None), Some("left"), Some("any"), global = false, Some("L"), pmid :: Nil)
)
Expand Down
7 changes: 7 additions & 0 deletions app/models/entities/Enums.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package models.entities

object ComparatorEnum extends Enumeration {
type Comparator = Value

val GreaterThan, LesserThan = Value
}
6 changes: 5 additions & 1 deletion app/models/entities/Publication.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ case class Publication(
pmid: String,
pmcid: Option[String],
date: String,
year: Int,
month: Int,
sentences: Option[JsValue]
)

object Publication {
implicit val getSimilarityRowFromDB: GetResult[Publication] =
GetResult(r => Publication(r.<<[Long].toString, r.<<?, r.<<, r.<<?[String].map(Json.parse)))
GetResult(r =>
Publication(r.<<[Long].toString, r.<<?, r.<<, r.<<, r.<<, r.<<?[String].map(Json.parse))
)

implicit val similarityImp: OFormat[Publication] = Json.format[Publication]

Expand Down
16 changes: 15 additions & 1 deletion app/models/gql/Arguments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package models.gql

import models.entities.Configuration._
import models.entities.Pagination._
import models.entities._
import models.entities.{ComparatorEnum, _}
import sangria.macros.derive._
import sangria.schema._
import sangria.marshalling.playJson._
Expand Down Expand Up @@ -63,6 +63,20 @@ object Arguments {
"Use disease ontology to capture evidences from all descendants to build associations"
)

val ComparerEnum = deriveEnumType[ComparatorEnum.Value](
IncludeValues("GreaterThan", "LesserThan")
)

val year: Argument[Option[Int]] =
Argument("year", OptionInputType(IntType), description = "Year")
val month: Argument[Option[Int]] =
Argument("month", OptionInputType(IntType), description = "Month")
val dateComparator: Argument[Option[ComparatorEnum.Value]] = Argument(
"comparator",
OptionInputType(ComparerEnum),
description = "Defines if should results be either before or after specific date"
)

val BFilterString: Argument[Option[String]] = Argument("BFilter", OptionInputType(StringType))
val scoreSorting: Argument[Option[String]] = Argument("orderByScore", OptionInputType(StringType))

Expand Down
12 changes: 10 additions & 2 deletions app/models/gql/Objects.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,20 @@ object Objects extends Logging {
"Return the list of publications that mention the main entity, " +
"alone or in combination with other entities"
),
arguments = idsArg :: cursor :: Nil,
arguments = idsArg :: year :: month :: dateComparator :: cursor :: Nil,
resolve = c => {
val ids = c.arg(idsArg).getOrElse(List.empty) ++ List(c.value.id)
val filterYear = c.arg(year)
val filterMonth = c.arg(month)
val filterDateComparator = c.arg(dateComparator)
val cur = c.arg(cursor)

c.ctx.getLiteratureOcurrences(ids.toSet, cur)
c.ctx.getLiteratureOcurrences(ids.toSet,
filterYear,
filterMonth,
filterDateComparator,
cur
)
}
),
Field(
Expand Down

0 comments on commit 4dd26f5

Please sign in to comment.