2014-11-22 2 views
1

Цель состоит в том, чтобы фильтровать элементы с необязательными ключевыми словами и/или shopId.Построение динамического запроса с помощью Slick 2.1.0

Если ни один из них не определен, все элементы должны быть возвращены.

Моя попытка

case class ItemSearchParameters(keywords: Option[String], shopId: Option[Long]) 

def search(params: ItemSearchParameters): Either[Failure, List[Item]] = { 
    try { 
     db withDynSession { 
     val q = Items.query 
     if (params.keywords.isDefined) { 
      q.filter { i => 
      ((i.title like "%" + params.keywords + "%") 
      || (i.description like "%" + params.keywords + "%")) 
      } 
     } 
     if (params.shopId.isDefined) { 
      q.filter { i => 
      i.shopId === params.shopId 
      } 
     } 
     Right(q.run.toList) 
     } 
    } catch { 
     case e: SQLException => 
     Left(databaseError(e)) 
    } 
    } 

params.keywords или params.ShopId определена эта функция вернула все элементы. Может кто-нибудь объяснить, что не так?


Update: вторая попытка

def search(params: ItemSearchParameters): Either[Failure, List[Item]] = { 
    try { 
     db withDynSession { 
     var q = Items.query 
     q = params.keywords.map{ k => q.filter(_.title like "%" + k + "%")} getOrElse q 
     q = params.keywords.map{ k => q.filter(_.description like "%" + k + "%")} getOrElse q 
     q = params.shopId.map{ sid => q.filter(_.shopId === sid)} getOrElse q 
     Right(q.run.toList) 
     } 
    } catch { 
     case e: SQLException => 
     Left(databaseError(e)) 
    } 
    } 

Для второй попытки, как это сделать (название или описание), если ключевые слова isDefined?


Update: Третья попытка с MaybeFilter Не работает

case class MaybeFilter[X, Y](val query: scala.slick.lifted.Query[X, Y, Seq]) { 
    def filteredBy(op: Option[_])(f:(X) => Column[Option[Boolean]]) = { 
    op map { o => MaybeFilter(query.filter(f)) } getOrElse { this } 
    } 
} 


class ItemDAO extends Configuration { 

    implicit def maybeFilterConversor[X,Y](q:Query[X,Y,Seq]) = new MaybeFilter(q) 

    def search(params: ItemSearchParameters): Either[Failure, List[Item]] = { 
    try { 
     db withDynSession { 
     val q = Items 
      .filteredBy(params.keywords){i => ((i.title like "%" + params.keywords + "%") 
      || (i.description like "%" + params.keywords + "%"))} 
      .filteredBy(params.shopId){_.shopId === params.shopId} 
      .query 
     Right(q.list) 
     } 
    } catch { 
     case e: SQLException => 
     Left(databaseError(e)) 
    } 
    } 
} 

Третьей попытки возвращает пустой список, если ключевые слова даются

ответ

0
def search(params: ItemSearchParameters): Either[Failure, List[Item]] = { 
    try { 
     db withDynSession { 
     var q = Items.query 

     q = params.keywords.map{ k => q.filter(
      i => (i.title like "%" + k + "%") 
       || (i.description like "%" + k + "%") 
     )} getOrElse q 

     q = params.shopId.map{ sid => q.filter(
      _.shopId === sid 
     )} getOrElse q 

     Right(q.run.toList) 
     } 
    } catch { 
     case e: SQLException => 
     Left(databaseError(e)) 
    } 
    } 

Я не уверен, что это лучший ответ из-за var q

0

Как я понял, вы rrect, вы хотите создать фильтр по необязательным полям. Ваша вторая попытка спокойна ближе к реальности, первая имеет неправильное совпадение, вы сравниваете поля опций с опцией non. Вы ответили на свой ответ, в то время как я писал этот ответ :)

я хотел бы рекомендовать вам этот MaybeFilter https://gist.github.com/cvogt/9193220

Или здесь модифицированную версию: https://github.com/neowinx/hello-slick-2.1-dynamic-filter/blob/master/src/main/scala/HelloSlick.scala#L3-L7

Может быть, это может помочь вам решают вашу проблему более общим образом.

+0

Спасибо, я просто попытался использовать его, но я не мог заставить его работать с ключевыми словами. См. Третью попытку в моем вопросе :) – arsenik

+0

О, я вижу, нужно увидеть сгенерированный запрос.) – DaunnC