FQL v4 will be decommissioned on June 30, 2025. Ensure that you complete your migration from FQL v4 to FQL v10 by that date. Fauna accounts created after August 21, 2024 must use FQL v10. These accounts will not be able to run FQL v4 queries or access the v4 Dashboard. For more details, see the v4 EOL announcement and migration guide. Contact support@fauna.com with any questions. |
Defensive query strategies
This section describes recommended best practices for handling queries on non-existent documents or fields.
When a document does not exist
Fauna document relationships are commonly made by storing References to other documents. However, if document A stores a reference to document B, the reference to document B is not changed in document A when document B is deleted. Subsequent queries that process document A fail when they attempt to fetch document B.
You can handle references to deleted documents by calling the If
and
Exists
functions to test for the existence of a document before
attempting to fetch it.
For example, the following query fails because the related document does not exist.
Error: [NotFound] instance not found: Document not found.
Error: <class 'faunadb.errors.NotFound'> ErrorData(code='instance not found', description='Document not found.', position=['let', 2, 'owner'], failures=None)
Response error 404. Errors: [let//owner](instance not found): Document not found., details: []
ERROR: instance not found: Document not found.
ERROR com.faunadb.client.errors.NotFoundException: instance not found: Document not found.
{
errors: [
{
position: [
'let',
2,
'owner'
],
code: 'instance not found',
description: 'Document not found.'
}
]
}
The following query succeeds because it checks for the existence of the
related document. The non-existence of the document can be reported, for
example, by substituting an object that includes the DISAPPEARED
name.
{ spellbook: "Dallben's Spellbook", owner: 'DISAPPEARED' }
{'spellbook': "Dallben's Spellbook", 'owner': 'DISAPPEATED'}
map[owner:DISAPPEARED spellbook:Dallben's Spellbook]
ObjectV(spellbook: StringV(Dallben's Spellbook),owner: StringV(DISAPPEARED))
{spellbook: "Dallben's Spellbook", owner: "DISAPPEARED"}
{ spellbook: "Dallben's Spellbook", owner: 'DISAPPEARED' }
When a field does not exist
The flexible Fauna data model allows documents with different structures to coexist in a single collection. When evaluating documents with inconsistent field structures, attempting to access a non-existent field causes your query to fail.
You can test for the existence of a field using the If
and
ContainsPath
functions.
For example, the following query fails because not all documents contain the
extra
field.
Error: [NotFound] value not found: Value not found at path [data,extra].
Error: <class 'faunadb.errors.NotFound'> ErrorData(code='value not found', description='Value not found at path [data,extra].', position=['map', 'expr', 'in', 'object', 'extra', 'concat', 1, 'to_string', 'from'], failures=None)
Response error 404. Errors: [map/expr/in/object/extra/concat//to_string/from](value not found): Value not found at path [data,extra]., details: []
ERROR: value not found: Value not found at path [data,extra].
ERROR com.faunadb.client.errors.NotFoundException: value not found: Value not found at path [data,extra].
{
errors: [
{
position: [
'map',
'expr',
'in',
'object',
'extra',
'concat',
1,
'to_string',
'from'
],
code: 'value not found',
description: 'Value not found at path [data,extra].'
}
]
}
The following query succeeds because the existence of the extra
field is
checked and if the field does not exist, it can be reported, for example, by
returning UNDEFINED
.
{
data: [
{ letter: 'A', extra: 'Extra-First' },
{ letter: 'B', extra: 'Extra-second' },
{ letter: 'C', extra: 'Extra-third' },
{ letter: 'D', extra: 'Extra-4th' },
{ letter: 'E', extra: 'Extra-fifth' },
{ letter: 'F', extra: 'Extra-sixth' },
{ letter: 'G', extra: 'Extra-seventh' },
{ letter: 'H', extra: 'Extra-eighth' },
{ letter: 'I', extra: 'Extra-9th' },
{ letter: 'J', extra: 'Extra-tenth' },
{ letter: 'K', extra: 'Extra-11' },
{ letter: 'L', extra: 'Extra-' },
{ letter: 'M', extra: 'UNDEFINED' },
{ letter: 'N', extra: 'Extra-14th' },
{ letter: 'O', extra: 'Extra-fifteenth' },
{ letter: 'P', extra: 'Extra-16th' },
{ letter: 'Q', extra: 'Extra-seventeenth' },
{ letter: 'R', extra: 'Extra-18th' },
{ letter: 'S', extra: 'Extra-19th' },
{ letter: 'T', extra: 'Extra-20th' },
{ letter: 'U', extra: 'Extra-21st' },
{ letter: 'V', extra: 'Extra-22nd' },
{ letter: 'W', extra: 'Extra-twenty-third' },
{ letter: 'X', extra: 'Extra-24' },
{ letter: 'Y', extra: 'Extra-24 + 1' },
{ letter: 'Z', extra: 'UNDEFINED' }
]
}
{'data': [{'letter': 'A', 'extra': 'Extra-First'}, {'letter': 'B', 'extra': 'Extra-second'}, {'letter': 'C', 'extra': 'Extra-third'}, {'letter': 'D', 'extra': 'Extra-4th'}, {'letter': 'E', 'extra': 'Extra-fifth'}, {'letter': 'F', 'extra': 'Extra-sixth'}, {'letter': 'G', 'extra': 'Extra-seventh'}, {'letter': 'H', 'extra': 'Extra-eighth'}, {'letter': 'I', 'extra': 'Extra-9th'}, {'letter': 'J', 'extra': 'Extra-tenth'}, {'letter': 'K', 'extra': 'Extra-11'}, {'letter': 'L', 'extra': 'Extra-'}, {'letter': 'M', 'extra': 'UNDEFINED'}, {'letter': 'N', 'extra': 'Extra-14th'}, {'letter': 'O', 'extra': 'Extra-fifteenth'}, {'letter': 'P', 'extra': 'Extra-16th'}, {'letter': 'Q', 'extra': 'Extra-seventeenth'}, {'letter': 'R', 'extra': 'Extra-18th'}, {'letter': 'S', 'extra': 'Extra-19th'}, {'letter': 'T', 'extra': 'Extra-20th'}, {'letter': 'U', 'extra': 'Extra-21st'}, {'letter': 'V', 'extra': 'Extra-22nd'}, {'letter': 'W', 'extra': 'Extra-twenty-third'}, {'letter': 'X', 'extra': 'Extra-24'}, {'letter': 'Y', 'extra': 'Extra-24 + 1'}, {'letter': 'Z', 'extra': 'UNDEFINED'}]}
map[data:[map[extra:Extra-First letter:A] map[extra:Extra-second letter:B] map[extra:Extra-third letter:C] map[extra:Extra-4th letter:D] map[extra:Extra-fifth letter:E] map[extra:Extra-sixth letter:F] map[extra:Extra-seventh letter:G] map[extra:Extra-eighth letter:H] map[extra:Extra-9th letter:I] map[extra:Extra-tenth letter:J] map[extra:Extra-11 letter:K] map[extra:Extra- letter:L] map[extra:UNDEFINED letter:M] map[extra:Extra-14th letter:N] map[extra:Extra-fifteenth letter:O] map[extra:Extra-16th letter:P] map[extra:Extra-seventeenth letter:Q] map[extra:Extra-18th letter:R] map[extra:Extra-19th letter:S] map[extra:Extra-20th letter:T] map[extra:Extra-21st letter:U] map[extra:Extra-22nd letter:V] map[extra:Extra-twenty-third letter:W] map[extra:Extra-24 letter:X] map[extra:Extra-24 + 1 letter:Y] map[extra:UNDEFINED letter:Z]]]
ObjectV(data: Arr(ObjectV(letter: StringV(A),extra: StringV(Extra-First)), ObjectV(letter: StringV(B),extra: StringV(Extra-second)), ObjectV(letter: StringV(C),extra: StringV(Extra-third)), ObjectV(letter: StringV(D),extra: StringV(Extra-4th)), ObjectV(letter: StringV(E),extra: StringV(Extra-fifth)), ObjectV(letter: StringV(F),extra: StringV(Extra-sixth)), ObjectV(letter: StringV(G),extra: StringV(Extra-seventh)), ObjectV(letter: StringV(H),extra: StringV(Extra-eighth)), ObjectV(letter: StringV(I),extra: StringV(Extra-9th)), ObjectV(letter: StringV(J),extra: StringV(Extra-tenth)), ObjectV(letter: StringV(K),extra: StringV(Extra-11)), ObjectV(letter: StringV(L),extra: StringV(Extra-)), ObjectV(letter: StringV(M),extra: StringV(UNDEFINED)), ObjectV(letter: StringV(N),extra: StringV(Extra-14th)), ObjectV(letter: StringV(O),extra: StringV(Extra-fifteenth)), ObjectV(letter: StringV(P),extra: StringV(Extra-16th)), ObjectV(letter: StringV(Q),extra: StringV(Extra-seventeenth)), ObjectV(letter: StringV(R),extra: StringV(Extra-18th)), ObjectV(letter: StringV(S),extra: StringV(Extra-19th)), ObjectV(letter: StringV(T),extra: StringV(Extra-20th)), ObjectV(letter: StringV(U),extra: StringV(Extra-21st)), ObjectV(letter: StringV(V),extra: StringV(Extra-22nd)), ObjectV(letter: StringV(W),extra: StringV(Extra-twenty-third)), ObjectV(letter: StringV(X),extra: StringV(Extra-24)), ObjectV(letter: StringV(Y),extra: StringV(Extra-24 + 1)), ObjectV(letter: StringV(Z),extra: StringV(UNDEFINED))))
{data: [{letter: "A", extra: "Extra-First"}, {letter: "B", extra: "Extra-second"}, {letter: "C", extra: "Extra-third"}, {letter: "D", extra: "Extra-4th"}, {letter: "E", extra: "Extra-fifth"}, {letter: "F", extra: "Extra-sixth"}, {letter: "G", extra: "Extra-seventh"}, {letter: "H", extra: "Extra-eighth"}, {letter: "I", extra: "Extra-9th"}, {letter: "J", extra: "Extra-tenth"}, {letter: "K", extra: "Extra-11"}, {letter: "L", extra: "Extra-"}, {letter: "M", extra: "UNDEFINED"}, {letter: "N", extra: "Extra-14th"}, {letter: "O", extra: "Extra-fifteenth"}, {letter: "P", extra: "Extra-16th"}, {letter: "Q", extra: "Extra-seventeenth"}, {letter: "R", extra: "Extra-18th"}, {letter: "S", extra: "Extra-19th"}, {letter: "T", extra: "Extra-20th"}, {letter: "U", extra: "Extra-21st"}, {letter: "V", extra: "Extra-22nd"}, {letter: "W", extra: "Extra-twenty-third"}, {letter: "X", extra: "Extra-24"}, {letter: "Y", extra: "Extra-24 + 1"}, {letter: "Z", extra: "UNDEFINED"}]}
{
data: [
{ letter: 'A', extra: 'Extra-First' },
{ letter: 'B', extra: 'Extra-second' },
{ letter: 'C', extra: 'Extra-third' },
{ letter: 'D', extra: 'Extra-4th' },
{ letter: 'E', extra: 'Extra-fifth' },
{ letter: 'F', extra: 'Extra-sixth' },
{ letter: 'G', extra: 'Extra-seventh' },
{ letter: 'H', extra: 'Extra-eighth' },
{ letter: 'I', extra: 'Extra-9th' },
{ letter: 'J', extra: 'Extra-tenth' },
{ letter: 'K', extra: 'Extra-11' },
{ letter: 'L', extra: 'Extra-' },
{ letter: 'M', extra: 'UNDEFINED' },
{ letter: 'N', extra: 'Extra-14th' },
{ letter: 'O', extra: 'Extra-fifteenth' },
{ letter: 'P', extra: 'Extra-16th' },
{ letter: 'Q', extra: 'Extra-seventeenth' },
{ letter: 'R', extra: 'Extra-18th' },
{ letter: 'S', extra: 'Extra-19th' },
{ letter: 'T', extra: 'Extra-20th' },
{ letter: 'U', extra: 'Extra-21st' },
{ letter: 'V', extra: 'Extra-22nd' },
{ letter: 'W', extra: 'Extra-twenty-third' },
{ letter: 'X', extra: 'Extra-24' },
{ letter: 'Y', extra: 'Extra-24 + 1' },
{ letter: 'Z', extra: 'UNDEFINED' }
]
}
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!