My table data forms a tree structure where one row can reference a parent row in the same table.
What I am trying to achieve, using Slick, is to write a query that will return a row and all it's children. Also, I would like to do the same, but write a query that will return a child and all it's ancestors.
In other words:
findDown(1) should return
List(Group(1, 0, "1"), Group(3, 1, "3 (Child of 1)"))
findUp(5) should return
List(Group(5, 2, "5 (Child of 2)"), Group(2, 0, "2"))
Here is a fully functional worksheet (except for the missing solutions ;-).
package com.exp.worksheets
import scala.slick.driver.H2Driver.simple._
object ParentChildTreeLookup {
implicit val session = Database.forURL("jdbc:h2:mem:test1;", driver = "org.h2.Driver").createSession()
session.withTransaction {
Groups.ddl.create
}
Groups.insertAll(
Group(1, 0, "1"),
Group(2, 0, "2"),
Group(3, 1, "3 (Child of 1)"),
Group(4, 3, "4 (Child of 3)"),
Group(5, 2, "5 (Child of 2)"),
Group(6, 2, "6 (Child of 2)"))
case class Group(
id: Long = -1,
id_parent: Long = -1,
label: String = "")
object Groups extends Table[Group]("GROUPS") {
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def id_parent = column[Long]("ID_PARENT")
def label = column[String]("LABEL")
def * = id ~ id_parent ~ label <> (Group, Group.unapply _)
def autoInc = id_parent ~ label returning id into {
case ((_, _), id) => id
}
def findDown(groupId: Long)(implicit session: Session) = { ??? }
def findUp(groupId: Long)(implicit session: Session) = { ??? }
}
}
A really bad, and static attempt at findDown may be something like:
private def groupsById = for {
group_id <- Parameters[Long]
g <- Groups; if g.id === group_id
} yield g
private def childrenByParentId = for {
parent_id <- Parameters[Long]
g <- Groups; if g.id_parent === parent_id
} yield g
def findDown(groupId: Long)(implicit session: Session) = { groupsById(groupId).list union childrenByParentId(groupId).list }
But, I'm looking for a way for Slick to recursively search the same table using the id and id_parent link. Any other good ways to solve the problem is really welcome. Keep in mind though, that it would be best to minimise the number of database round-trips.
Kind regards,
Jacobus
Relational queries are not suited for tree-like structures. You mentioned in stack overflow post that the depth of your trees will typically be shallow. Why not implement the recursion on the client side, along the lines of your supposedly bad findDown implementation shown here? You may run n queries with n being the depth of your tree, but if your tree is shallow, is that a problem? Otherwise I would agree with the recommendations on stack overflow. Either implement a stored procedure in the DB and hook it into Slick or use some database which has support for tree queries such as H2.
your http://stackoverflow.com/questions/15070620/recursive-tree-like-table-query-with-slick
--
---
You received this message because you are subscribed to the Google Groups "Slick / ScalaQuery" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scalaquery+...@googlegroups.com.
Should I treat these like one would normally write plain SQL using Slick, or are there any gotcha's I should be aware of?
Relational queries are not suited for tree-like structures. You mentioned in stack overflow post that the depth of your trees will typically be shallow. Why not implement the recursion on the client side, along the lines of your supposedly bad findDown implementation shown here? You may run n queries with n being the depth of your tree, but if your tree is shallow, is that a problem? Otherwise I would agree with the recommendations on stack overflow. Either implement a stored procedure in the DB and hook it into Slick or use some database which has support for tree queries such as H2.
your http://stackoverflow.com/questions/15070620/recursive-tree-like-table-query-with-slick
--
---
You received this message because you are subscribed to the Google Groups "Slick / ScalaQuery" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scalaquery+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.