Scala Slick: получение количества полей с определенным значением в группе по запросу - PullRequest
0 голосов
/ 25 мая 2018

У меня есть такая таблица:

|``````````````````````````|
|imgId, pageId, isAnnotated|
|1,      1,       true     |
|2,      1,       false    |
|3,      2,       true     |
|4,      1,       false    |
|5,      3,       false    |
|6,      2,       true     |
|7,      3,       true     |
|8,      3,       true     |
|__________________________|

Я хочу получить результат как:

|`````````````````````````````````````|
|pageId, imageCount, noOfAnotatedImage|
|   1          3          1           |
|   2          2          2           |
|   3          3          2           |
|_____________________________________|

Я хочу, чтобы количество аннотированных изображений на основе числового поля было установлено какtrue.

Код Slick, который я пробовал, который вызвал исключение:

  def get = {
    val q = (for {
      c <- WebImage.webimage
    } yield (c.pageUrl, c.lastAccess, c.isAnnotated)).groupBy(a => (a._1, a._3)).map{
      case(a,b) => (a._1, b.map(_._2).max, b.filter(_._3 === true).length, b.length)
    }
    db.run(q.result)
  }

Исключение:

[SlickTreeException: Cannot convert node to SQL Comprehension
| Path s6._2 : Vector[t2<{s3: String', s4: Long', s5: Boolean'}>]
]

Примечание: Это Подсчитать общее количество записейсодержащие конкретные значения thread clear показывает, что в простом SQL все, что мне нужно, возможно.

SELECT
   Type
  ,sum(case Authorization when 'Accepted' then 1 else 0 end) Accepted
  ,sum(case Authorization when 'Denied' then 1 else 0 end) Denied
 from MyTable
 where Type = 'RAID'
 group by Type

Изменен код, но все еще появляется исключение:

Execution exception
[SlickException: No type for symbol s2 found for Ref s2]

In /home/ravinder/IdeaProjects/structurer/app/scrapper/Datastore.scala:60
56  def get = {
57    val q = (for {
58      c <- WebImage.webimage
59    } yield (c.pageUrl, c.lastAccess, c.isAnnotated)).groupBy(a => (a._1, a._3)).map{
[60]      case(a,b) => (a._1, b.map(_._2).max, b.map(a => if (a._3.result == true) 1 else 0 ).sum, b.length)
61    }
62    db.run(q.result)
63  }
64

1 Ответ

0 голосов
/ 25 мая 2018

Учитывая ваше требование, вы должны сгруппировать только по pageUrl, чтобы выполнить агрегирование по всем строкам для одной и той же страницы.Вы можете агрегировать lastAccess с помощью max и isAnnotated с помощью sum над условным Case.If-Then-Else.Slick-запрос должен выглядеть примерно так:

val q = (for {
    c <- WebImage.webimage
  } yield (c.pageUrl, c.lastAccess, c.isAnnotated)).
  groupBy( _._1 ).map{ case (url, grp) =>
    val lastAcc = grp.map( _._2 ).max
    val annoCnt = grp.map( _._3 ).map(
        anno => Case.If(anno === true).Then(1).Else(0)
      ).sum
    (url, lastAcc, annoCnt, , grp.length)
  }
...