Data types

FQL uses an enhanced Javascript Object Notation (JSON) format for storing and communicating data. JSON is a human and machine-readable open standard that facilitates data interchange. All of JSON’s basic types are supported, including Number, String, Boolean values, as well as Array and Object.

Basic types

Type Description

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.

{ my_boolean: true }

Null

Null is a special marker used to indicate that a data value does not exist. It is a representation of missing information, indicating 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.

{ my_null: null }

Number

Numbers are any real number which are bounded by the double precision range (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.

FQL accepts and communicates strings as UTF-8 encoded strings. For string functions, any arguments or returned values which utilize offsets and lengths operate using code points.

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

Array

An Array is a data structure that contains a group of elements. 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' ]

Object

The Object type represents a JSON-like object, where its values are a collection of key/value pairs. The keys must be strings and the values must be valid FQL 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 }

Special types

In addition to the basic types, FQL supports the following types beyond those native to JSON:

Type Description

Byte

The Bytes type 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]
{0 62135596800 <nil>}
[0x01 0x02 0x03]
bytearray(b'\x01\x02\x03')
#<Fauna::Bytes:0x00007fc06582e1c8>
[0x01 0x02 0x03]
Bytes("AQID")

Date

The Date type 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' }

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 (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 functions that accept arrays, 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.

Query

The Query type denotes a query expression object.

Ref

The Ref type denotes a resource reference. Refs may be extracted from documents, or constructed using the Collection, Database, Function, Index, or Role functions, or the general-purpose Ref function.

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

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

Set

The Set type denotes a set identifier. A set is a group of tuples, typically representing resources or index terms, that are in a specific order.

curl https://db.fauna.com/ \
    -u fnAChGwBcAACAO70ziE0cfROosNJHdgBmJU1PgpL: \
    -d '{
          "@set": {
            "match": { "@ref": "indexes/spells_by_element" },
            "terms": "fire"
          }
        }'
client.Query(Match(Index("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(Index("spells_by_element"), "fire"))
client.query(q.match(Index("spells_by_element"), "fire"))
$client.query do
  match index('spells_by_element'), 'fire'
end
client.query(
    Match(
        index: Index("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", collection = 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

The Timestamp type (usually written as ts) stores an instant in time expressed as a calendar date and time of day in UTC.

A Timestamp can safely store nanosecond 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 Timestamp 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' }

Events

Strictly speaking, events aren’t types; they are objects that capture the temporal history of documents by tracking all create, update, and delete operations over a document’s timeline. However, they have a common structure:

Document events

Field Value Description

ref

Ref

The reference to the document.

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 events

Set events are represented by an object returned when paginating through an index.

Field Value Description

ref

Ref

The reference to the document.

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’s terms field.

Precedence

Types have an order of precedence. When comparing values of different types, they are ranked in the following order, from greatest to least. For example, a double is sorted before an integer because of its type.

  1. Number (integers and decimals: 0.5 < 1 < 1.5 < 2)

  2. String

  3. Array

  4. Object

  5. Boolean

  6. Date

  7. Timestamp

  8. Ref

  9. Null

Was this article helpful?

We're sorry to hear that.
Tell us how we can improve! documentation@fauna.com

Thank you for your feedback!