Data Types

FQL supports a comprehensive set of data types which are broken down into four categories: Simple types, Special types, Collection types and Complex types. A simple data type is one that is native to FaunaDB, and to JSON. Special data types in FaunaDB extend the limited number of native JSON data types. Each complex data type is a composite of other existing data types. The collection data type is able to handle multiple items while maintaining order.

Simple Type Special Type Complex Type Collection Type

Simple types

Simple data types contain a key and simple value which is native to both Fauna and JSON. For example, a string containing the word "cat" or a number with the value 21.

Boolean

The boolean data type can only store "true" or "false" values. These can be directly compared for equality or inequality. They can also be compared to the Boolean literal values of true and false.

Null

Null is a special marker used to indicate that a data value does not exist. It is a representation of missing information. A null value indicates a lack of a value. A lack of a value is not the same thing as a value of zero, in the same way that a lack of an answer is not the same thing as an answer of "no". Null is a value that can be directly compared for application programmer simplicity. This means that Null == Null returns true.

Number

Numbers are any real number which are bounded by double precision (64-bit), such as 3, -27, 3.1415. (Neither infinity nor NaN are allowed.)

String

String data types store any letters, numbers, whitespaces, and/or symbols in a fixed order.

Special types

FaunaDB supports types beyond those native to JSON. These types are referred to as Special Types and are encoded as JSON objects with a single field. The field name is one of several type tags that specify the type of the value. Type tags always start with @.

Bytes

@bytes denotes a base64 encoded string representing a byte array.

curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '{ "@bytes": "AQID" }'
client.Query(new BytesV(0x1, 0x2, 0x3));
System.out.println(client.query(Value(new byte[]{ 0x1, 0x2, 0x3 })).get());
result, _ := client.Query(f.BytesV{0x1, 0x2, 0x3})

fmt.Println(result)
client.query(Array[Byte](0x1, 0x2, 0x3))
client.query(bytearray(b'\x01\x02\x03'))
$client.query do
  Fauna::Bytes.new("\01\02\03")
end
client.query(BytesV(fromArray: [0x1, 0x2, 0x3]))
client.query(new Uint8Array([0x1, 0x2, 0x3]))
  .then((ret) => console.log(ret));
HTTP/1.1 200 OK
{ "resource": { "@bytes": "AQID" } }
{ "@bytes": "AQID" }
[0x01 0x02 0x03]
[1 2 3]
{ "@bytes": "AQID" }
{ "@bytes": "AQID" }
{ "@bytes": "AQID" }
{ "@bytes": "AQID" }
Bytes("AQID")

Date

@date denotes a date, with no associated time zone.

curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '{ "@date": "1970-01-01" }'
client.Query(Date("1970-01-01"));
System.out.println(client.query(Date(Value("1970-01-01"))).get());
result, _ := client.Query(f.Date("1970-01-01"))

fmt.Println(result)
client.query(Date("1970-01-01"))
client.query(q.date("1970-01-01"))
$client.query do
  date '1970-01-01'
end
client.query(DateFn("1970-01-01"))
client.query(q.Date("1970-01-01"))
  .then((ret) => console.log(ret));
HTTP/1.1 200 OK
{ "resource": { "@date": "1970-01-01" } }
{ "@date": "1970-01-01" }
1970-01-01
{0 62135596800 <nil>}
{ "@date": "1970-01-01" }
{ "@date": "1970-01-01" }
{ "@date": "1970-01-01" }
{ "@date": "1970-01-01" }
FaunaDate { value: '1970-01-01' }

Query

@query denotes a query expression object.

Ref

@ref denotes a resource ref. Refs may be extracted from instances, or constructed using the ref function.

curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '{ "@ref": "classes/spells/181388642071085568" }'
client.Query(Select("ref", Get(Class("spells"))));
System.out.println(client.query(Select(Value("ref"), Get(Class("spells")))).get());
result, _ := client.Query(f.Select("ref", f.Get(f.Class("spells"))))
fmt.Print(result)
print client.query(q.select("ref", q.get(q.class_("spells"))))
puts $client.query { select "ref", get(class_("spells")) }
client.query(Select("ref", Get(Class("spells"))))
client.query(q.Select("ref", q.Get(q.Class("spells"))))
  .then((ret) => console.log(ret))
HTTP/1.1 200 OK
{ "resource": { "@ref": "classes/spells/181388642071085568" } }
{ "@ref": "classes/spells/181388642071085568" }
ref(id = "spells", class = ref(id = "classes"))
{spells 0xc4201f4a60 <nil>}
RefV(id = "spells", class = RefV(id = "classes"))
Ref(id=spells, class=Ref(id=classes))
Ref(id=spells,class=Ref(id=classes))
{ "@ref": "classes/spells/181388642071085568" }
Ref(id=spells, class=Ref(id=classes))
curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '{ "ref": { "class": "spells" }, "id": "1" }'
client.Query(Ref(Class("spells"), "1"));
System.out.println(client.query(Ref(Class(Value("spells")),Value(1))).get());
result, _ := client.Query(f.RefClass(f.Class("spells"), "1"))

fmt.Println(result)
client.query(Ref(Class("spells"), "1"))
client.query(Ref(q.class_expr("spells"), "1"))
$client.query do
  ref class_('spells'), '1'
end
client.query(Ref(class: Class("spells"), id: "1"))
client.query(q.Ref(q.Class("spells"), "1"));
  .then((ret) => console.log(ret));
HTTP/1.1 200 OK
{ "resource": { "@ref": "classes/spells/1" } }
{ "@ref": "classes/spells/1" }
ref(id = "1", class = ref(id = "spells", class = ref(id = "classes")))
{1 0xc420138620 <nil>}
{ "@ref": "classes/spells/1" }
{ "@ref": "classes/spells/1" }
{ "@ref": "classes/spells/1" }
{ "@ref": "classes/spells/1" }
Ref(id=1, class=Ref(id=spells, class=Ref(id=classes)))

Set

@set denotes a set identifier.

curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '{
          "@set": {
            "match": { "@ref": "indexes/spells_by_element" },
            "terms": "fire"
          }
        }'
client.Query(Match(Ref("indexes/spells_by_element"), "fire"));
System.out.println(
        client.query(
                Match(
                     Index(Value("spells_by_element")),
                     Value("fire")
                )
        ).get());
result, _ := client.Query(
  f.MatchTerm(f.Index("spells_by_element"), "fire"),
)

fmt.Println(result)
client.query(Match(Ref("indexes/spells_by_element"), "fire"))
client.query(q.match(Ref("indexes/spells_by_element"), "fire"))
$client.query do
  match ref('indexes/spells_by_element'), 'fire'
end
client.query(
    Match(
        index: Ref("indexes/spells_by_element"),
        terms: "fire"
    )
)
client.query(q.Match(q.Index("spells_by_element"), "fire"))
  .then((ret) => console.log(ret));
HTTP/1.1 200 OK
{
  "resource": {
    "@set": {
      "match": { "@ref": "indexes/spells_by_element" },
      "terms": "fire"
    }
  }
}
{
  "@set": {
    "match": { "@ref": "indexes/spells_by_element" },
    "terms": "fire"
  }
}
{@set = {match: ref(id = "spells_by_element", class = ref(id = "indexes")), terms: "fire"}}
{map[match:{spells_by_element 0xc4201a6360 <nil>} terms:fire]}
{
  "@set": {
    "match": { "@ref": "indexes/spells_by_element" },
    "terms": "fire"
  }
}
{
  "@set": {
    "match": { "@ref": "indexes/spells_by_element" },
    "terms": "fire"
  }
}
{
  "@set": {
    "match": { "@ref": "indexes/spells_by_element" },
    "terms": "fire"
  }
}
{
  "@set": {
    "match": { "@ref": "indexes/spells_by_element" },
    "terms": "fire"
  }
}
SetRef({"match":{"@ref":{"id":"spells_by_element","class":{"@ref":{"id":"indexes"}}}},"terms":"fire"})

Timestamp

@ts stores an instant in time expressed as a calendar date and time of day in UTC. A Timestamp can safely store nanoseconds precision, but be careful as many operating system clocks provide only microsecond precision. Timestamps may be inserted with offsets, but are converted to UTC; the offset component is lost. A time must be within the range -999999999-01-01T00:00:00Z - 9999-12-31T23:59:59.999999999Z.

curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '{ "time": "1970-01-01T00:00:00Z" }'
client.Query(Time("1970-01-01T00:00:00Z"));
System.out.println(client.query(Time(Value("1970-01-01T00:00:00Z"))).get());
result, _ := client.Query(f.Time("1970-01-01T00:00:00Z"))

fmt.Println(result)
client.query(Time("1970-01-01T00:00:00Z"))
client.query(q.time("1970-01-01T00:00:00Z"))
$client.query do
  time '1970-01-01T00:00:00Z'
end
client.query(Time(fromString: "1970-01-01T00:00:00Z"))
client.query(q.Time("1970-01-01T00:00:00Z"))
  .then((ret) => console.log(ret))
HTTP/1.1 200 OK
{ "resource": { "@ts": "1970-01-01T00:00:00Z" } }
{ "@ts": "1970-01-01T00:00:00Z" }
1970-01-01T00:00:00Z
{0 62135596800 <nil>}
{ "@ts": "1970-01-01T00:00:00Z" }
{ "@ts": "1970-01-01T00:00:00Z" }
{ "@ts": "1970-01-01T00:00:00Z" }
{ "@ts": "1970-01-01T00:00:00Z" }
FaunaTime { value: '1970-01-01T00:00:00Z' }

Complex types

Object

Object values are a collection of key/value pairs. The keys must be strings and the values must be valid Fauna data types. The value expressions are evaluated sequentially in the order that they were specified, left to right. Objects evaluate to their contents:

curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '{
          "object": { "name": "Hen Wen", "age": { "add": [ 100, 10 ] } }
        }'
client.Query(Obj("name", "Hen Wen", "age", Add(100, 10)));
System.out.println(
  client.query(
    Obj("name", Value("Hen Wen"), "age", Add(Value(100), Value(10)))
  ).get());
result, _ := client.Query(f.Obj{"name": "Hen Wen", "age": f.Add(100, 10)})

fmt.Println(result)
client.query(Obj("name" -> "Hen Wen", "age" -> Add(100, 10)))
client.query({"name": "Hen Wen", "age": q.add(100, 10)})
$client.query do
  { name: 'Hen Wen', age: add(100, 10) }
end
client.query(
    Obj("name" => "Hen Wen", "age" => Add(100, 10))
)
client.query({ name: "Hen Wen", age: q.Add(100, 10) })
  .then((ret) => console.log(ret));
HTTP/1.1 200 OK
{ "resource": { "name": "Hen Wen", "age": 110 } }
{ "name": "Hen Wen", "age": 110 }
{ name: "Hen Wen", age: 110 }
map[age:110 name:Hen Wen]
{ "name": "Hen Wen", "age": 110 }
{ "name": "Hen Wen", "age": 110 }
{ "name": "Hen Wen", "age": 110 }
{ "name": "Hen Wen", "age": 110 }
{ name: 'Hen Wen', age: 110 }

Instance

Instance Event

An InstanceEvent tracks the history of the instance’s data over time. The events in this history include all create, update, and delete events in the instance’s timeline.

Field Value Description

instance

Ref

The reference to the instance.

action

Either "create","update" or "delete".

ts

An integer value representing a UNIX timestamp, with microsecond resolution, at which the event occurred.

data

Varies based on the action.

Set Event

A SetEvent is an object returned when paginating through an index.

Field Value Description

instance

Ref

The reference to the instance.

action

Either "add" or "remove".

ts

An integer value representing a UNIX timestamp, with microsecond resolution, at which the event occurred.

data

Exactly as defined by the index.

Collection types

A Collection data type represents a group of items. The collection is an array or is an object that contains an array as one of its elements.

Array

An array is a data structure that contains a group of elements. Typically the elements of an array are of the same or related type. When an array is used in FQL it evaluates to its contents.

curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '[ 1, 2, { "concat": [ "Hen ", "Wen" ] } ]'
client.Query(Arr(1, 2, Concat(Arr("Hen ", "Wen"))));
System.out.println(client.query(
         Arr(
             Value(1),
             Value(2),
             Concat(Arr(Value("Hen "), Value("Wen")))
         )).get());
result, _ := client.Query(f.Arr{1, 2, f.Concat(f.Arr{"Hen ", "Wen"})})

fmt.Println(result)
client.query(Arr(1, 2, Concat(Arr("Hen ", "Wen"))))
client.query([1, 2, q.concat(["Hen ", "Wen"])])
$client.query do
  [1, 2, concat(['Hen ', 'Wen'])]
end
client.query(Arr(1, 2, Concat("Hen ", "Wen")))
client.query([1, 2, q.Concat(["Hen ", "Wen"])])
  .then((ret) => console.log(ret));
HTTP/1.1 200 OK
{ "resource": [ 1, 2, "Hen Wen" ] }
[ 1, 2, "Hen Wen" ]
[1, 2, "Hen Wen"]
[1, 2, Hen Wen]
[ 1, 2, "Hen Wen" ]
[ 1, 2, "Hen Wen" ]
[ 1, 2, "Hen Wen" ]
[ 1, 2, "Hen Wen" ]
[ 1, 2, 'Hen Wen' ]

Page

A Page contains an array of results and other "decorated" elements. In some cases the entire result set may not fit into the array so other fields (the cursor fields) allow you to walk the results set in blocks (i.e. like pages in a book). The cursor fields retrieve blocks of results before or after the current page of results. When Pages are passed to collection functions, only the array element of the Page is examined or transformed. Other elements of the Page, such as the cursor, remain unaffected and are passed directly through to the output.

Field Type Description

data

The elements in the page.

after

Cursor

The cursor for the next page, inclusive. Optional.

before

Cursor

The cursor for the previous page, exclusive. Optional.

Literal

A literal is a constant value for a given data type. Boolean, Number, String, and Null all evaluate to their associated type:

true, false   // Boolean
1, 2          // Number
3.4, 1.2e10   // Number
"a", "b"      // String
null          // Null