Skip to content
rktoomey edited this page May 13, 2011 · 2 revisions

Child Collection

To facilitate working with child collections using a typed parent id, SalatDAO provides ChildCollection, an inner abstract class within SalatDAO that also extends SalatDAO.

In addition to all the regular SalatDAO methods, ChildCollection offers methods for working with a child collection using typed parent ids:

  • count by parent id
  • find typed child ids using a typed parent id
  • find, update and remove by parent id
  • projections by parent id

Getting started

Declare child collections inside an instance of SalatDAO typed to the parent class and id:

  case class ChildInfo(lastUpdated: DateTime = DateTime.now)
  case class Child(@Key("_id") id: Int,
                   parentId: ObjectId,
                   x: String,
                   childInfo: ChildInfo = ChildInfo(),
                   y: Option[String] = None)
  case class Parent(@Key("_id") id: ObjectId = new ObjectId, name: String)

  object ParentDAO extends SalatDAO[Parent, ObjectId](collection = MongoConnection()("test_db")("parent_coll")) {

    val children = new ChildCollection[Child, Int](collection = MongoConnection()("test_db")("child_coll"),
      parentIdField = "parentId") {}

  }

Finding by parent id

  val parent1 = Parent(name = "parent1")
  val parent2 = Parent(name = "parent2")
  val parent3 = Parent(name = "parent3")
  ParentDAO.insert(parent1, parent2, parent3)

  val child1Parent1 = Child(id = 1, parentId = parent1.id, x = "child1Parent1", y = Some("child1Parent1"))
  val child2Parent1 = Child(id = 2, parentId = parent1.id, x = "child2Parent1")
  val child3Parent1 = Child(id = 3, parentId = parent1.id, x = "child3Parent1")
  val child1Parent2 = Child(id = 4, parentId = parent2.id, x = "child1Parent2", y = Some("child1Parent2"))
  val child2Parent2 = Child(id = 5, parentId = parent2.id, x = "child2Parent2", y = Some("child2Parent2"))
  ParentDAO.children.insert(child1Parent1, child2Parent1, child3Parent1, child1Parent2, child2Parent2)

  // returns List[Child](child1Parent1, child2Parent1, child3Parent1)
  val r1 = ParentDAO.children.findByParentId(parent1.id).toList
  // Nil
  val r2 = ParentDAO.children.findByParentId(parent3.id).toList

Finding child ids by parent id

  // returns List[Int](1, 2, 3)
  val childIds = ParentDAO.children.idsForParentId(parent1.id).toList

Counting by parent id

  // count is three
  val count = ParentDAO.children.countByParentId(parent1.id)

  // you can also include fields to include or exclude
  val count2 = ParentDAO.children.countByParentId(parentId = parent1.id,
        fieldsThatMustExist = List("x"))  // count2 = 3
  val count3 = ParentDAO.children.countByParentId(parentId = parent1.id,
        fieldsThatMustExist = List("x"),
        fieldsThatMustNotExist = List("y")) // count3 = 2
  val count4 = ParentDAO.children.countByParentId(parentId = parent1.id,
        fieldsThatMustExist = List("x", "y")) // count4 = 1

Updating children by parent id

  val newLastUpdated = new DateMidnight(1812, FEBRUARY, 7).toDateTime
  val updateQuery = MongoDBObject("$set" -> MongoDBObject("childInfo.lastUpdated" -> newLastUpdated))
  // if everything went ok, cr.ok() should be true
  val cr = ParentDAO.children.updateByParentId(parent1.id, updateQuery, false, true)

Removing childen by parent id

  // if everything went ok, cr.ok() should be true
  val cr = ParentDAO.children.removeByParentId(parent1.id)

  // now Nil - we just removed them all
  val r1 = ParentDAO.children.findByParentId(parent1.id).toList

Projections by parent id

  // returns List[String]("child1Parent2", "child2Parent2")
  val r1 = ParentDAO.children.primitiveProjectionsByParentId[String](parent2.id, "x")
  // returns List[ChildInfo](child1Parent2.childInfo, child2Parent2.childInfo)
  val r2 = ParentDAO.children.projectionsByParentId[ChildInfo](parent2.id, "childInfo")