Query composition
The Fauna client drivers compose queries using FQL template strings. You can interpolate variables, including other FQL template strings, into the template strings to compose dynamic queries.
For example, using the JavaScript driver:
import { Client, fql, FaunaError } from "fauna";
const client = new Client({
secret: 'FAUNA_SECRET'
});
// Create a native JS var.
const name = "avocados";
// Pass the var to an FQL query.
let query = fql`Product.where(.name == ${name})`;
let response = await client.query( query );
console.log(response.data);
client.close();
To prevent injection attacks, the drivers use the wire protocol encode interpolated variables to an appropriate FQL type before passing the query to the Core HTTP API’s Query endpoint.
Example: Product catalog search
An e-commerce app has a product catalog that users search by various criteria, such as product category, price range, or other properties. A user may search by product type, minimum price, maximum price, or any combination of these criteria.
The following dynamic query handles various combinations of these search parameters:
import { Client, fql, FaunaError } from "fauna";
const client = new Client({
secret: 'FAUNA_SECRET'
});
// Set up parameterized inclusive, exclusive,
// or exact matches.
const operators = {
eq: (field, value) => fql`x => x[${field}] == ${value}`,
gt: (field, value) => fql`x => x[${field}] > ${value}`,
gte: (field, value) => fql`x => x[${field}] >= ${value}`,
lt: (field, value) => fql`x => x[${field}] < ${value}`,
lte: (field, value) => fql`x => x[${field}] <= ${value}`,
}
// Define the product search parameters set in the UI.
const predicates = [
{ field: "type", operator: "eq", value: "food" },
{ field: "price", operator: "lte", value: 10000 },
{ field: "price", operator: "gte", value: 10 },
];
const base_query = fql`Product`
// Chain successive `where()` methods to the query,
// effectively ANDing the predicates.
const dynamicQuery = predicates.reduce(
(acc, val) =>
fql`${acc}.where( ${operators[val.operator] ( val.field, val.value)})`,
base_query
)
let response = await client.query(dynamicQuery)
console.log(response.data)
client.close();
For simplicity, the example uses
collection.where()
, which
requires a read of each document and isn’t performant on large datasets. For
better performance, use indexes instead.
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!