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: instance not found: Document not found.
Response error 404. Errors: [let//owner](instance not found): Document not found., details: []
ERROR com.faunadb.client.errors.NotFoundException: instance not found: Document not found.
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)
{
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.
ObjectV(spellbook: StringV(Dallben's Spellbook),owner: StringV(DISAPPEARED))
map[owner:DISAPPEARED spellbook:Dallben's Spellbook]
{spellbook: "Dallben's Spellbook", owner: "DISAPPEARED"}
{ spellbook: "Dallben's Spellbook", owner: 'DISAPPEARED' }
{'spellbook': "Dallben's Spellbook", 'owner': 'DISAPPEATED'}
{ 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: value not found: Value not found at path [data,extra].
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 com.faunadb.client.errors.NotFoundException: value not found: Value not found at path [data,extra].
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)
{
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
.
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))))
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]]]
{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' }
]
}
{'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!