An entity in Datomic is a group of Datoms/facts that share an entity id:

Attributes with any seemingly unrelated namespaces can group as entities by simply sharing the entity id:

Entity API

At runtime we can see the facts of an entity by calling touch on the entity id (of type Long):

101L.touch === Map(
  ":db/id" -> 101L,
  ":person/name"  -> "Fred", 
  ":person/likes" -> "pizza", 
  ":person/age"   -> 38, 
  ":person/addr"  -> 102L,        // reference to an address entity with entity id 102 
  ":site/cat"     -> "customer"

Optional attribute values

We can look for an optionally present attribute value. Here we ask the entity id fredId if it has a :site/cat attribute value (of type String) and we get a typed optional value back:

val siteCat_? : Option[String] = fredId[String](":site/cat")


The touch method can recursively retrieve referenced entities. We could for instance traverse an Order with LineItems:

orderId.touch === Map(
  ":db/id" -> orderId,
  ":order/lineItems" -> List(
      ":db/id" -> 102L, 
      ":lineItem/qty" -> 3, 
      ":lineItem/product" -> "Milk",
      ":lineItem/price" -> 12.0),
      ":db/id" -> 103L, 
      ":lineItem/qty" -> 2, 
      ":lineItem/product" -> "Coffee",
      ":lineItem/price" -> 46.0)))

The entity attributes graph might be deep and wide so we can apply a max level to touch(<maxLevel>):

fredId.touch(2) === Map(
  ":db/id" -> fredId,
  ":person/name" -> "Fred"
  ":person/friends" -> List(
      ":db/id" -> lisaId,
      ":person/name" -> "Lisa"
      ":person/friends" -> List(
          ":db/id" -> monaId,
          ":person/name" -> "Mona"
          ":person/friends" -> Set(ids...) // Mona's friends (3 levels deep) only as ids - not attribute maps
        Map(...) // + more friends of Lisa (2 levels deep)
    Map(...) // + more friends of Fred (1 level deep)


The entity API is not type-safe so in Relationships we will look at various ways of traversing referenced data in type-safe ways with Molecule.