Check out v4 of the Fauna CLI
v4 of the Fauna CLI is now in beta. The new version introduces enhancements to the developer experience, including an improved authentication workflow. To get started, check out the CLI v4 quick start. |
FQL syntax quick look
This gives you a quick look at the Fauna Query Language (FQL) syntax.
FQL is similar to JavaScript with influences from TypeScript and GraphQL, differing from those languages in that it is optimized for database operations.
Basic syntax
// Single-line comments start with double-slash.
/*
Block comments start with slash-asterisk
and end with asterisk-slash.
*/
// Statements don't have to be terminated by ; ...
(1 + 3) * 2
// ... but can be.
(1 + 3) * 2;
/////////////////////////////////////////////
// Numbers, Strings, and Operators
// FQL has integer, decimal, and exponential values stored as
// Int, Long, or Double types, which are all Number types.
// An Int is a signed 32-bit integer type.
// A Long is a signed 64-bit integer type.
// Doubles are double-precision, 64-bit binary type, IEEE 754-2019.
3 // 3
1.5 // 1.5
3.14e5 // 314000.0
// Some basic arithmetic works as you'd expect.
1 + 1 // 2
0.1 + 0.2 // 0.30000000000000004
8 - 1 // 7
10 * 2 // 20
35 / 5 // 7
// Including uneven division.
5 / 2 // 2
// Precedence is enforced with parentheses.
(1 + 3) * 2 // 8
// There's also a boolean type.
true
false
// Strings are created with ' or ".
'abc' // "abc"
"Hello, world" // "Hello, world"
// Negation uses the ! symbol
!true // false
!false // true
// Equality is ==
1 == 1 // true
2 == 1 // false
// Inequality is !=
1 != 1 // false
2 != 1 // true
// More comparisons
1 < 10 // true
1 > 10 // false
2 <= 2 // true
2 >= 2 // true
// Strings are concatenated with +
"Hello " + "world!" // "Hello world!"
// and are compared with < and >
"a" < "b" // true
// Type coercion isn't performed for comparisons with double equals...
"5" == 5 // false
// You can access characters in a string with at() built-in string method.
"This is a string".at(0) // "T"
// ...or use an index.
"Hello world"[0] // "H"
// "length" is a property so don't use ().
"Hello".length // 5
// There's also "null".
null; // used to indicate a deliberate non-value
// false, null, 0, and "" are falsy; everything else is truthy.
/////////////////////////////////////////////
// Arrays, and Objects
// Arrays are ordered lists containing values, of any type.
let myArray = ["Hello", 45, true]
myArray // ["Hello", 45, true]
// Their members can be accessed using the square-brackets subscript syntax.
// Array indices start at zero. You can also use the `at()` built-in method.
myArray[1] // 45
myArray.at(1) // 45
// Arrays are of variable length.
myArray.length // 3
// Accessing an Array index greater than or equal to the Array length:
myArray[3] // results in an error.
// Create an Array from elements in the range index 1 (include) to
// index 4 (exclude).
myArray.slice(1, 4) // [45, true]
// FQL objects are equivalent to "dictionaries" or "maps" in other
// languages: an unordered collection of key:value pairs. You can use
// the dot syntax provided the key is a valid identifier.
let myObj = {key1: "Hello", key2: "World"}
myObj.key1 // "Hello"
// Keys are strings but quotes aren't required if they're a valid
// JavaScript identifier. Values can be any type.
let myObj = {myKey: "myValue", "myOtherKey": 4}
// Object attributes can also be accessed using the subscript syntax.
myObj.myKey // "myValue"
myObj.myOtherKey // 4
// If you try to access a value not yet set, you'll get an error.
myObj.myThirdKey // results in an error.
/////////////////////////////////////////////
// Variables
// Use the "let" keyword to declare variables in a lexical scope and
// assign a value to the variable. FQL is dynamically typed, so you don't
// need to specify type. Assignment uses a single = character. Also, "let"
// can't be the last statement, because it isn't an expression.
let someVar = 5
someVar // 5
// A variable in the same scope can be assigned a new value:
let someVar = 5
let someVar = 6
someVar // 6
// You can declare only one variable in the same `let` statement.
/////////////////////////////////////////////
// Control structures, logic
// The `if ... else` structure works as you'd expect.
let count = 1
if (count == 3) {
// evaluated if count is 3
} else if (count == 4) {
// evaluated if count is 4
} else {
// evaluated if not 3 or 4
}
// `&&` is logical AND, `||` is logical OR
let house = {size: "big", color: "blue"}
if (house.size == "big" && house.color == "blue") {
"big blue house"
}
if (house.color == "red" || house.color == "blue") {
"red or blue"
}
/////////////////////////////////////////////
// Block scope
// A block is defined with `{ }` and variables are scoped to the block.
// Variables outside of the block are global.
// The last statement in a block must be an expression.
let greeting = "hi"
{
let greeting = "hello"
greeting
} // "hello"
let greeting = "hi"
{
let greeting = "hello"
greeting
}
greeting // "hi"
/////////////////////////////////////////////
// Anonymous functions
// FQL anonymous functions are declared using the short-form
// arrow syntax. An anonymous function can't be called before the definition.
(x) => {
let greeting = "hello"
greeting
}
// Objects can contain functions.
let myFunc = {
(x) => {
let double = x + x
double
}
}
myFunc(3) // 6
// Some built-in methods accept single-argument functions.
Customer.all().where(c => c.address.zipCode == "20002")
// Which is equivalent to:
let myFunc = {
(c) => {
c.address.zipCode == "20002"
}
}
Customer.all().where(myFunc)
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!