Mar 29, 2018


Blog Categories

Categories

Blog Categories

Getting Started with FaunaDB: Fauna Query Language (FQL)

Previously in my Quick Start Guide, I demonstrated how to create a database and perform basic write and read operations through the Cloud dashboard. In this post we dive into the use of FQL (Fauna Query Language), which is the main interface for all interactions with FaunaDB. FQL is a powerful yet approachable and flexible query language. As in my previous post, we'll use Fauna Cloud to illustrate our examples, but you can also apply examples to an instance of FaunaDB deployed on-premises.

Overview

FQL is an expression-oriented language. It supports common application-level constructs such as variables, loops and conditional logic. It also supports a rich set of functional programming and relational database utilities such as map, filter, union, join, distinct, etc. While not a general purpose programming language, FQL provides much of the functionality expected from one, allowing for complex, precise manipulation and retrieval of data stored within your database.

Since FaunaDB is a fully consistent and transactional system, an entire query commits atomically. Imagine, for example, a query that loads a range from an index, iterates over the rows, then runs conditional logic to load more data and update some of the documents. Since the entire query commits atomically, no changes are committed if something goes wrong along the way. So you’re not left with data in a half-written state.

FQL Drivers

The Fauna Query Language is available throughdrivers in several popular programming languages. As of this writing these include: Java, Javascript, Scala, Ruby, C#, Python, Go and Swift. Each driver provides a domain-specific language allowing you to encode queries in the language of your choice.

Each driver is available as an import in its language’s standard library import interface. For Javascript, the driver is available as a package on npm and is imported like this:

var fdb = require('faunadb');

FaunaDB Query Construction

With a driver imported into your code, you’ll have tools at your disposal for creating transactional queries. The fdb.query object contains all of the functions to create query expressions programmatically. In Javascript we can save this to a variable q for convenience and brevity:

var q = fdb.query;

Constructing a query will often involve nesting together a series of query expressions. Detailed documentation on all of the available functions can be found in our Query Syntax Reference.

FaunaDB Query Client

A FaunaDB client is used to send queries to your database. This client needs to have access to your database. Access is granted via a key secret during client instantiation. (Refer to step 3 of my Quick Start Guide for how to generate a database-level service key.)

var client = new faunadb.Client({  secret: 'YOUR_FAUNADB_SECRET'
});

The query you build with the fdb.query functions can be executed against your database by passing it through this client:

client.query(  q.Get(Ref("classes/my_items/1"))
);

You can group multiple queries into one client call by bundling them into an array, like this:

client.query(  [    q.Get(Ref("classes/my_items/1")),    q.Get(Ref("classes/my_items/2")),    q.Get(Ref("classes/my_items/3"))  ]
);

Hands-on Examples

Let’s move on from theoretical chatter about FQL and get you actually executing some queries! There’s no environment or driver setup needed to follow along with these examples since the Cloud dashboard includes a query console where you can execute queries programmatically using the Javascript driver.

Visit https://fauna.com/sign-up to sign up for your FaunaDB account. Once you have an account set up, go to  https://dashboard.fauna.com/ and click the Toggle Query Console link in the bottom right corner:

The query console in the Cloud dashboard is a convenient way to experiment and execute FQL in the context of your FaunaDB Cloud environment.

Notes about the query console:

  • There is no need to import a driver since the Javascript driver is built in.
  • There is no need to import a driver since the Javascript driver is built in.
  • Your code should contain only query expressions since the dashboard will execute your code in a client.query() statement for you.

A variable q exists in the console which is equivalent to fdb.query as described above.

The below example builds on the examples from ourprevious post where you constructed a database, class and index for a to-do list. Enter the following code snippet in your query console then click Run to practice writing and reading programmatically in your database:

// Create an additional to-do item (an instance of the my_items class)
q.Create(q.Class("my_items"), {  data: { title: "call dad" }
});
// Get all the instances of the my_items class
q.Paginate(  q.Match(    q.Index("all_my_items")  )
);

Conclusion

If you’re familiar with other NoSQL solutions, you may have noticed many similarities with their query languages. However, unlike other NoSQL solutions, FQL offers the added benefits of supporting transactions, joins, unique constraints, user-defined functions and other relational features that are typically only found in traditional SQL systems. And since FaunaDB is document-relational, your documents look like JSON, but they can have references to other documents and you can follow these references like a graph in your queries.

The examples in this post cover just the basics of getting started programmatically interacting with FaunaDB. Much more is possible with more advanced queries. Ready to keep learning? Explore our documentation ( https://fauna.com/documentation ). You can also check out the Query Syntax Reference ( https://fauna.com/documentation/reference/queryapi ) since it contains details on all FQL functions.

If you enjoyed this topic and want to work on systems and challenges just like this, Fauna is hiring!