2012-05-05 5 views
3

Есть ли у кого-нибудь идея о том, как много архивировать в Scala Query?
ScalaQuery много для многих

Я хочу связать сообщение в блоге с тегами.
Это мой дизайн базы данных: enter image description here

мне удалось с моим пользовательским кодом, но при проверке Scala Querys генерируется SQL Я не доволен своим решением.
Я играл с функциональным подходом, и он сгенерировал множество SQL-запросов, что привело к множеству круглых поездок.
Я могу выяснить, как уменьшить количество запросов примерно наполовину.

Рука созданного запроса, который получает все мои данные хорошо отформатированные в одном запросе,

select 
    p.id, p.content, p.posted_date, GROUP_CONCAT(t.name) 
from 
    post p, 
    tag t, 
    tag_post tp 
where 
    tp.post_id = p.id and tp.tag_id = t.id 
group by 
    p.id 

Сформированные запросы от Scala Query дает одни и те же данные.

SELECT `t1`.`id`,`t1`.`content`,`t1`.`posted_date` FROM `post` `t1` 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=2) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=3) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=4) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=5) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=6) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=7) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=8) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=9) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=10) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=11) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=12) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=13) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=14) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=15) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=16) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=17) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=2) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=18) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=19) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=1) 
SELECT `t1`.`id`,`t1`.`name` FROM `tag` `t1` WHERE (`t1`.`id`=3) 
SELECT `t1`.`tag_id` FROM `tag_post` `t1` WHERE (`t1`.`post_id`=20) 

Я беспокоюсь, что это может быть связано с большими расходами со всеми этими поездками.

Есть ли кто-нибудь, кто успел сделать хороший запрос Scala для многих вариантов?

ответ

3

EDIT
Вы можете моделировать GROUP_CONCAT так:

val groupConcat = SimpleFunction[String]("GROUP_CONCAT") 

При создании этого метода в рамках запроса, он должен быть столь же просто, как:

yield (alias.a, alias.b, groupConcat(alias.c)) 

Поскольку я храню эти вспомогательные функции в абстрактной оболочке базы данных и реализовать в определенных СУБД, таких как MySQL, она становится немного более сложной, так как подпись типа SimpleFunction требует, чтобы этот абстрактный метод определялся ition:

val groupConcat: (Seq[Column[_]] => OperatorColumn[String]) 

Это означает, что реализация требует, чтобы перейти в послед (alias.c), который немного счетчик интуитивно, мы просто проездом в одной колонке. Во всяком случае, к счастью, она работает, GROUP_CONCAT очень удобно в MySQL

ORIGINAL
Бог знает, что это неправильно, не отправляя код, но попробуйте это:

val q = (for { 
    tp <- TagPost 
    p <- Post if tp.post_id is p.id 
    t <- Tag if tp.tag_id is t.id 
    _ <- Query groupBy p.id 
} yield (p.id, p.content, p.posted_date, group_concat(t.name))) 
println(q.selectStatement) 

Вы будете должны создайте функцию для репликации GROUP_CONCAT MySQL. См. SimpleFunction source; унарный метод этого объекта позволяет передать в именованный столбец базовую функцию СУБД.

val group_concat = 
    SimpleFunction.unary[NamedColumn[String], String]("GROUP_CONCAT") 
+0

Спасибо, это был почти точный мой запрос поначалу. Да, вы пригвоздили проблему, поскольку вы получаете только сообщение, но не связанные теги, все запросы к запросу Scala вытесняли этот результат тегами. Мне не нужно использовать группу concat, если есть способ получить ее как список в запросе scala напрямую. Я отвечаю на Ipad, как только посмотрю, смогу ли продлить SQ позже сегодня. – Farmor

+0

Aha Я вижу, что вы обновили свой ответ, теперь он выглядит очень многообещающим. Думаю, мне нужно вручную разобрать результат для создания моего объекта. Поскольку я не нормально выставляю явные столбцы, но объекты, определенные в «объекте», расширяют таблицу со своим классом класса компаньона. – Farmor

+0

@Farmor получил работу group_concat, см. Править. Вышеупомянутый должен повторить требуемый ручной SQL. ScalaQuery продолжает впечатлять ... – virtualeyes

1

Я наконец-то закончил с использованием метода.
К сожалению, это специфический поставщик.

def allPosts = database.withSession { implicit db: Session => 
    val group_concat_string_tmp = SimpleFunction[String]("GROUP_CONCAT") 
    def group_concat_string(c: Column[String]) = group_concat_string_tmp(Seq(c)) 
    def group_concat_long(c: Column[Long]) = group_concat_string_tmp(Seq(c)) 
    val query = for{ 
     tp <- TagPostTable 
     tag <- TagTable if tp.tag_id is tag.id 
     post <- PostTable if tp.post_id is post.id 
     _ <- Query groupBy post.id 
    } yield post.id ~ post.content ~ post.postedDate ~ group_concat_long(tag.id) ~ group_concat_string(tag.name) 
    println(query.selectStatement) 
    def parseToTagList(ids: String, names: String) : List[Tag] = { 
     (ids.split(',') map (_.toLong) , names.split(',')).zipped map (Tag(_,_)) toList 
    } 
    query.list map (queryResult => Post(queryResult._1, queryResult._2, queryResult._3, Option(parseToTagList(queryResult._4, queryResult._5)))) 
    } 

И сгенерированный SQL-запрос является исключительным :) ДА!

SELECT `t1`.`id`,`t1`.`content`,`t1`.`posted_date`,GROUP_CONCAT(`t2`.`id`),GROUP_CONCAT(`t2`.`name`) 
FROM `tag_post` `t3`,`post` `t1`,`tag` `t2` 
WHERE (`t3`.`tag_id`=`t2`.`id`) AND (`t3`.`post_id`=`t1`.`id`) 
GROUP BY `t1`.`id` 
Смежные вопросы