Fauna does not provide cascading deletes out-of-the-box for user-defined documents. That is, if you have a document "A" that includes a reference to another document "B", deleting "A" does not affect "B", and deleting "B" does not affect "A".
Cascading deletes can be achieved with FQL. As an example to demonstrate the solution, consider two collections Employee
and Payroll
, where the Payroll
collection has a reference to documents in the Employee
collection.
An example Employee
document looks like this:
{
ref: Ref(Collection("Employee"), "345160721616601289"),
ts: 1665429765270000,
data: {
name: "Claire",
title: "Manager",
department: "Finance",
location: "USA"
}
}
The corresponding document in the Payroll collection looks like this:
{
ref: Ref(Collection("Payroll"), "345231628271878345"),
ts: 1665497387100000,
data: {
employee: Ref(Collection("Employee"), "345160721616601289"),
salary: 5000
}
}
If you delete the Employee
document for Claire, it does not automatically delete the associated Payroll
document.
To do this, you will need to create an index on the Payroll
collection to get the Payroll
document based on the Employee ref.
CreateIndex({
name: "payroll_by_employee_ref",
source: Collection("Payroll"),
terms: [{ field: ["data", "employee"] }],
values: [{ field: "ref" }]
})
The following query deletes the employee Claire from the Employee
collection and uses the newly created index to delete the related entry from the Payroll
table at the same time.
Let(
{
emp_to_delete: Ref(Collection("Employee"), "345160721616601289"),
linked_references: Paginate(Match(Index("payroll_by_employee_ref"), Var("emp_to_delete")))
},
Do(
Delete(Var("emp_to_delete")),
Map(Var("linked_references"), Lambda("ref", Delete(Var("ref"))))
)
)
Output:
{
data: [
{
ref: Ref(Collection("Payroll"), "345231628271878345"),
ts: 1663800195650000,
data: {
employee: Ref(Collection("Employee"), "345160721616601289"),
}
}
]
}
This can be further extended to delete Employee
references in multiple collections at the same time by creating necessary indexes in each of those collections and applying a Union to match them all.
For example, the following query fetches the Employee
document from two collections Payroll
and AccessDirectory
using indexes and deletes Employee
entries in both of them at the same time.
Let(
{
emp_to_delete: Ref(Collection("Employee"), "345160721616601289"),
linked_references: Paginate(
Union(
Match(Index("payroll_by_employee_ref"), Var("emp_to_delete")),
Match(Index("access_by_emp"), Var("emp_to_delete"))
)
)
},
Do(
Delete(Var("emp_to_delete")),
Map(Var("linked_references"), Lambda("ref", Delete(Var("ref"))))
)
)
Note: The query only deletes all the linked refs that fit to one page. Size option of Paginate needs to be adjusted if your indexes return more than 64 results.