Database document hydration
Documents are connected with each other via their document _id
.
For example:
a contact document is connected to its parent by storing their
_id
in theparent
propertya report document is connected to its submitter by storing their
_id
in thecontact
propertySee Also: DB Schema
To optimize database storage, documents are “minified” when stored and are “hydrated” when they are used by the app.
Minification
Minification means replacing a linked document’s content with an object that only contains its uuid. This is done to reduce duplication of data to save storage space on the client and server. Additionally, as we only have one copy of the data is easier to keep the information up to date.
Unminified object:
{
"_id": "clinic_uuid",
"name": "Clinic",
"type": "clinic",
"parent": {
"_id": "health_center_id",
"name": "Health Center",
"type": "health_center",
"parent": {
"_id": "district_hospital_id",
"name" : "District",
"type": "district_hospital"
}
},
"contact": {
"_id": "contact_id",
"name": "Primary contact",
"phone": "555 111 222"
},
"linked_docs": {
"tag1": {
"_id": "sibling_id",
"name": "Sibling clinic",
"type": "clinic"
},
"tag2": {
"_id": "supervisor_id",
"name": "The supervisor",
"type": "person"
}
}
}
when minified, becomes:
{
"_id": "clinic_uuid",
"name": "Clinic",
"type": "clinic",
"parent": {
"_id": "health_center_id",
"parent": {
"_id": "district_hospital_id"
}
},
"contact": {
"_id": "contact_id"
},
"linked_docs": {
"tag1": "sibling_id",
"tag2": "supervisor_id"
}
}
The following properties are minified:
parent
and recursively, every ancestorcontact
patient
andplace
are removed from reports. Theplace_id
,place_uuid
,patient_id
, orpatient_uuid
fields are available in the document.linked_docs
when minifying a contact (as of3.10.0
)
Hydration
Hydration represents the inverse process to minification, where a stored id representing a connected document is replaced with the corresponding document’s content.
Minified doc:
{
"_id": "clinic_uuid",
"name": "Clinic",
"type": "clinic",
"parent": {
"_id": "health_center_id",
"parent": {
"_id": "district_hospital_id"
}
},
"contact": {
"_id": "contact_id"
},
"linked_docs": {
"tag1": "sibling_id",
"tag2": "supervisor_id"
}
}
when hydrated becomes:
{
"_id": "clinic_uuid",
"name": "Clinic",
"type": "clinic",
"parent": {
"_id": "health_center_id",
"name": "Health Center",
"type": "health_center",
"contact": {
"_id": "supervisor_id",
"name": "Supervisor",
"type": "person",
"parent": {
"_id": "parent_id"
}
},
"parent": {
"_id": "district_hospital_id",
"name" : "District",
"type": "district_hospital",
"contact": {
"_id": "manager_id",
"name": "Manager",
"type": "person",
"parent": {
"_id": "parent_id"
}
}
}
},
"contact": {
"_id": "contact_id",
"name": "Primary contact",
"phone": "555 111 222",
"parent": {
"_id": "parent_id"
}
},
"linked_docs": {
"tag1": {
"_id": "sibling_id",
"name": "Sibling clinic",
"type": "clinic"
},
"tag2": {
"_id": "supervisor_id",
"name": "The supervisor",
"type": "person"
}
}
}
There are two types of hydration:
- shallow hydration - when the id is replaced with the document’s content
- deep hydration - when the id is replaced with the document’s content and, recursively, each ancestor is deeply hydrated
A hydrated contact has
- deeply hydrated
parent
along with every ancestor - shallowly hydrated primary
contact
- shallowly hydrated
linked_docs
(as of 3.10)
A hydrated report has
- a deeply hydrated submitter
contact
- a deeply hydrated
patient
, if the report has apatient_id
/patient_uuid
- a deeply hydrated
place
, if the report has aplace_id