computed fields are read-only field types that can transform and aggregate data from many records. Computed fields shift
the burden of query performance from you onto Gadget, so for aggregate queries like counts and sums, Gadget recommends
leveraging computed.
For example, if you wanted to display the total spend of a shopper on their profile, you could add a computed field called totalSpend to a customer model, and teach that field to store the results of a query that sums the total spend of the customer across all orders. By using computed fields, you no longer have to:
aggregate data ahead of time when you write it
remember to re-run the query when any of its inputs change (e.g. if a new order was placed by the customer)
keep the query performant or manage database indexes
Queries to the Gadget database via computed fields are written in Gelly, Gadget's expression language. Gelly is a simple and easy-to-learn language that closely resembles SQL and GraphQL. Learn more about Gelly in the Gelly guide.
Snippet syntax
Computed field Gelly snippets define a new field with the field keyword, and then have one expression within them. This expression can use other fields from the model to do rich computation.
For example, we can compute a customer record's fullName with the following Gelly snippet that uses the firstName and lastNamestring fields:
customer/fullName.gelly
gelly
fieldoncustomer{
concat([firstName," ", lastName])
}
Computed fields can do arithmetic as well, like computing a post's score from its upvotes and downvotes:
post/score.gelly
gelly
fieldonpost{
(upvotes - downvotes)*100
}
Computed fields can use data from related models, like computing the total spend of a customer:
customer/totalSpend.gelly
gelly
fieldoncustomer{
sum(orders.totalPrice)
}
Using a Computed field
You can create and use a computed field in three steps:
Add the field to the main model whose data you want to compute with and select the computed field type
Define the code for the field in the .gelly snippet file created for your field
Query the computed field in your API along with any other fields you like.
For example, say your app has a model named business with number fields revenue and costs. We can add a new computed field to the business model called profit with this Gelly snippet:
models/profit.gelly
gelly
fieldonbusiness{
revenue - costs
}
Then, we can query this field in our API like so:
JavaScript
1await api.business.findMany({
2select:{
3name:true,
4profit:true,
5},
6});
Your Gelly snippet can support a wide variety of operators and functions, for more information refer to the Gelly reference.
Accessing computed fields on the frontend through your API
computed fields can be accessed the same way as all your other fields from the frontend: using your API client or your
auto-generated GraphQL API.
const record =await api.someModel.findOne(123,{
select:{id:true,computedField:true},
});
console.log(record.computedField);// => value from the backend
On the frontend, computed fields are included by default if you don't pass a select param.
Accessing computed fields on the backend
On the backend, computed fields are excluded by default on the record object.
In order to keep your actions fast by default, Gadget does not include computed fields in the record object passed to your action code. Instead, you must load any computed field values manually if required for your action. See the performance section for more details.
For example, if working on the update action of a customer model, you wanted to access the value of the customer object's fullName computed field, you can load it with an API call:
Check spamminess of a post in a blog, where the post model has a markedAsSpamboolean column, and then a shadowBannedboolean column on a related author model:
post/isSpam.gelly
gelly
fieldonpost{
author.shadowBanned || markedAsSpam
}
Count the number of comments on a post:
post/commentCount.gelly
gelly
fieldonpost{
count(comments)
}
In an AI app with a chatMessage model that has a tokenCountnumber field describing how many tokens were used to generate the message, count the total number of tokens a user has used in the past 30 days:
Compute the length of the third side of a triangle with number fields for sides a and b:
triangle/c.gelly
gelly
fieldontriangle{
sqrt(power(a,exponent:2) + power(b,exponent:2))
}
Pricing
Including or excluding a computed field from your API calls in Gadget does not change the price of the API call. API calls are charged for the number of records returned, not the number of fields returned or the number of records scanned in the database. API calls will still be charged for database reads based on the number of records returned.
Gadget executes computed fields under the hood using SQL statements doing read-time aggregation. This means that if your computed field is aggregating over a significant number of records, it can take some time for your hosted database the execute the query. Gadget automatically optimizes the layout and indexes in your database to ensure your computed fields are computed quickly, but they can certainly add time to the duration of your API calls.
If you don't need the value of a computed field for a query, you can omit it from your query with select: { someComputedField: false } and it will not be computed.