diff --git a/src/main/scala/Engine.scala b/src/main/scala/Engine.scala index 133fb2c..03a9d2c 100644 --- a/src/main/scala/Engine.scala +++ b/src/main/scala/Engine.scala @@ -38,6 +38,7 @@ case class Query( currentDate: Option[String] = None, // if used will override dateRange filter, currentDate must lie between the item's // expireDateName value and availableDateName value, all are ISO 8601 dates dateRange: Option[DateRange] = None, // optional before and after filter applied to a date field + dateRanges: Option[List[DateRange]] = None, // optional before and after filters applied to a date field blacklistItems: Option[List[String]] = None, // default: whatever is in algorithm params or None returnSelf: Option[Boolean] = None, // means for an item query should the item itself be returned, defaults // to what is in the algorithm params or false diff --git a/src/main/scala/URAlgorithm.scala b/src/main/scala/URAlgorithm.scala index 5024dfa..edb9954 100644 --- a/src/main/scala/URAlgorithm.scala +++ b/src/main/scala/URAlgorithm.scala @@ -752,81 +752,39 @@ class URAlgorithm(val ap: URAlgorithmParams) /** get part of query for dates and date ranges */ def getFilteringDateRange(query: Query): Seq[JValue] = { + def isRangeDefined = (range: DateRange) => range.before.isDefined || range.after.isDefined + + def dateRangeToQuery(dateRanges: Seq[DateRange]): JValue = { + + def rangeAsJson(dateRange: DateRange): JValue = { + "range" -> ( + dateRange.name -> + ("gt" -> dateRange.after) ~ + ("lt" -> dateRange.before)) + } + + "constant_score" -> + ("filter" -> + ("bool" -> + ("must" -> (dateRanges filter isRangeDefined map rangeAsJson)))) ~ + ("boost" -> 0) + } + // currentDate in the query overrides the dateRange in the same query so ignore daterange if both val currentDate = query.currentDate.getOrElse(DateTime.now().toDateTimeISO.toString) - val json: Seq[JValue] = if (query.dateRange.nonEmpty && + val json: Seq[JValue] = if (query.dateRanges.getOrEmpty exists isRangeDefined) { + Seq(dateRangeToQuery(query.dateRanges.get)) + } else if (query.dateRange.nonEmpty && (query.dateRange.get.after.nonEmpty || query.dateRange.get.before.nonEmpty)) { - val name = query.dateRange.get.name - val before = query.dateRange.get.before.getOrElse("") - val after = query.dateRange.get.after.getOrElse("") - val rangeStart = s""" - |{ - | "constant_score": { - | "filter": { - | "range": { - | "$name": { - """.stripMargin - - val rangeAfter = s""" - | "gt": "$after" - """.stripMargin - - val rangeBefore = s""" - | "lt": "$before" - """.stripMargin - - val rangeEnd = s""" - | } - | } - | }, - | "boost": 0 - | } - |} - """.stripMargin - - var range = rangeStart - if (!after.isEmpty) { - range += rangeAfter - if (!before.isEmpty) range += "," - } - if (!before.isEmpty) range += rangeBefore - range += rangeEnd - - Seq(parse(range)) + Seq(dateRangeToQuery(Seq(query.dateRange.get))) } else if (ap.availableDateName.nonEmpty && ap.expireDateName.nonEmpty) { // use the query date or system date val availableDate = ap.availableDateName.get // never None val expireDate = ap.expireDateName.get - val available = s""" - |{ - | "constant_score": { - | "filter": { - | "range": { - | "$availableDate": { - | "lte": "$currentDate" - | } - | } - | }, - | "boost": 0 - | } - |} - """.stripMargin - val expire = s""" - |{ - | "constant_score": { - | "filter": { - | "range": { - | "$expireDate": { - | "gt": "$currentDate" - | } - | } - | }, - | "boost": 0 - | } - |} - """.stripMargin - - Seq(parse(available), parse(expire)) + val ranges = Seq( + DateRange(availableDate, Option(currentDate), None), + DateRange(expireDate, None, Option(currentDate))) + Seq(dateRangeToQuery(ranges)) } else { logger.info( """