Merge pull request #35 from actualbudget/ActualQL-Examples-Org

ActualQL Examples
This commit is contained in:
Rich Howell
2022-10-21 21:23:46 +01:00
committed by GitHub
5 changed files with 136 additions and 67 deletions

View File

@@ -0,0 +1,67 @@
---
title: 'ActualQL Examples'
---
## Searching by month or year
ActualQL supports various functions to convert data, as well as the ability to convert field data. For example, saying `{ $month: '2021-01-01' }` would come back with the month of `2021-01`. But we need a way to apply that to the `date` field, and we use `$transform` for that.
This part deserves better docs, but here's a reference example you can use to search by month or year:
```js
q('transactions')
.filter({ date: { $transform: '$month', $eq: '2021-01' } })
.select('*')
```
This would return all transactions in the month of `2021-01`. We've applied the `$month` function to the `date` field and applied the condition of equaling `2021-01`.
You can substitute `$year` to do the same thing for year.
## Total Amount per Payee between 6 Apr 2020 and 5 Apr 2021
```js
(await $query($q('transactions')
.filter({ $and: [ {date: { $gte: '2020-04-06'}}, {date: {$lte: '2021-04-05'}}]})
.groupBy('payee.name')
.orderBy('payee.name')
.select(['payee.name', {'amount': {$sum: '$amount'}}])
)).data.map((row) => { console.log(`${row['payee.name']}: ${row.amount/100}`) })
```
## Total Amount of all transactions with Note containing #interest (P) between 6 Apr 2020 and 5 Apr 2021
```js
(await $query($q('transactions')
.filter({ '$and': [
{'date': { '$gte': '2020-04-06'}},
{'date': {'$lte': '2021-04-05'}},
{'notes': {'$like': '%#interest (P)%'}} ]
})
.calculate({ '$sum': '$amount' })
)).data/100
```
or
```js
(await $query($q('transactions')
.filter({ '$and': [
{'date': { '$gte': '2020-04-06'}},
{'date': {'$lte': '2021-04-05'}},
{'notes': {'$like': '%#interest (P)%'}}
]})
.select({ 'total': { '$sum': '$amount' } })
)).data[0].total/100
```
## Total Amount per Category between 6 Apr 2020 and 5 Apr 2021
```js
(await $query($q('transactions')
.filter({ $and: [ {date: { $gte: '2020-04-06'}}, {date: {$lte: '2021-04-05'}}]})
.groupBy('category.name')
.orderBy(['category.group.sort_order','category.sort_order'])
.select(['category.group.name','category.name', {'amount': {$sum: '$amount'}}])
)).data.map((row) => { console.log(`${row['category.group.name']}/${row['category.name']}: ${row.amount/100}`) })
```

View File

@@ -0,0 +1,48 @@
---
title: 'ActualQL Functions'
---
## Joining tables
You might have noticed the `category.name` field in the first few examples. What exactly is that field, and why can't we just use `category`?
The `category` field in `transactions` is an `id`. You can give it a specific category id to filter by that; you don't want to give it a name like `Home` because multiple categories can exist with the same name in different groups. By giving it a category id, you know you are getting back transactions specific to that category.
However, you often don't have a category id and want to just quickly search by category name. Using the `.` operator in a field name will "poke through" to the referenced table and allow you access any fields on it. Here, we can access any fields on the `categories` table.
So filtering by `category.name` allows you to search by name instead of id. You could use any field for `category`; for example `{ 'category.is_income': true }` would find all income categories.
## Sorting
You can sort the results with the `orderBy` function:
```js
q('transactions')
.filter({ 'category.is_income': true })
.select('*')
.orderBy('category.name')
```
This returns transactions with an income category sorted by category name. You can also pass an array to `orderBy` to sort by multiple fields.
## Aggregate functions
You can specify aggregate functions in `select` for things like sums and counts. An example:
```js
q('transactions')
.filter({ 'category.name': 'Food' })
.select({ total: { $sum: 'amount' } })
```
This sums up the amount of all transactions with the `Food` category (usually, you will filter by date too). **Aggregate results must be named**; here we named it `total`. You will get an error if you don't name it. (In the future, we may remove this restriction)
Since it's so common to select a single aggregate expression, ActualQL provides a different method for running them: `calculate`. The above query could be rewritten as:
```js
q('transactions')
.filter({ 'category.name': 'Food' })
.calculate({ $sum: 'amount' })
```
Not only did we not have to name the result, `data` in the result will also be the summed value itself. If you use `select`, data will be an array with one element. The difference is in the above you just use `data`, but if you used `select` you'd have to use `data[0].total`.

View File

@@ -1,3 +1,9 @@
---
title: 'ActualQL Overview'
---
## Introduction
ActualQL is a new query language introduced in 0.0.129. This allows you to query data any way you like. For example, previously we provided a `filterTransactions` method that let you search transactions, but its behavior was baked into the backend. You couldn't change how transactions were sorted, search certain fields specifically, or sum the total amount.
ActualQL provides a lightweight syntax for querying data. It looks like this:
@@ -17,7 +23,7 @@ Currently the query language is mostly undocumented, but more docs will come soo
Until we have better docs, here are few things you can do with ActualQL.
## Run a query
## Running a query
You construct a query with `q` and run it with `runQuery`. The result is an object with a `data` prop. An example:
@@ -49,7 +55,7 @@ These two options gives you full control over how you want to handle split trans
_* There is a third option as well, `all`, which returns both transactions and subtransactions in a flat list. You only need this if doing something advanced._
## Search tansactions
## Searching transactions
Calling `filter` applies conditions to the query; only data that matches the given filters will be returned.
@@ -102,65 +108,4 @@ q('transactions')
.select('*')
```
The above will return transactions on `2021-01-01` **or** `2021-01-02`.
### Searching by month or year
ActualQL supports various functions to convert data, as well as the ability to convert field data. For example, saying `{ $month: '2021-01-01' }` would come back with the month of `2021-01`. But we need a way to apply that to the `date` field, and we use `$transform` for that.
This part deserves better docs, but here's a reference example you can use to search by month or year:
```js
q('transactions')
.filter({ date: { $transform: '$month', $eq: '2021-01' } })
.select('*')
```
This would return all transactions in the month of `2021-01`. We've applied the `$month` function to the `date` field and applied the condition of equaling `2021-01`.
You can substitute `$year` to do the same thing for year.
## Joining tables
You might have noticed the `category.name` field in the first few examples. What exactly is that field, and why can't we just use `category`?
The `category` field in `transactions` is an `id`. You can give it a specific category id to filter by that; you don't want to give it a name like `Home` because multiple categories can exist with the same name in different groups. By giving it a category id, you know you are getting back transactions specific to that category.
However, you often don't have a category id and want to just quickly search by category name. Using the `.` operator in a field name will "poke through" to the referenced table and allow you access any fields on it. Here, we can access any fields on the `categories` table.
So filtering by `category.name` allows you to search by name instead of id. You could use any field for `category`; for example `{ 'category.is_income': true }` would find all income categories.
## Sorting
You can sort the results with the `orderBy` function:
```js
q('transactions')
.filter({ 'category.is_income': true })
.select('*')
.orderBy('category.name')
```
This returns transactions with an income category sorted by category name. You can also pass an array to `orderBy` to sort by multiple fields.
## Aggregate functions
You can specify aggregate functions in `select` for things like sums and counts. An example:
```js
q('transactions')
.filter({ 'category.name': 'Food' })
.select({ total: { $sum: 'amount' } })
```
This sums up the amount of all transactions with the `Food` category (usually, you will filter by date too). **Aggregate results must be named**; here we named it `total`. You will get an error if you don't name it. (In the future, we may remove this restriction)
Since it's so common to select a single aggregate expression, ActualQL provides a different method for running them: `calculate`. The above query could be rewritten as:
```js
q('transactions')
.filter({ 'category.name': 'Food' })
.calculate({ $sum: 'amount' })
```
Not only did we not have to name the result, `data` in the result will also be the summed value itself. If you use `select`, data will be an array with one element. The difference is in the above you just use `data`, but if you used `select` you'd have to use `data[0].total`.
The above will return transactions on `2021-01-01` **or** `2021-01-02`.

View File

@@ -1,5 +1,5 @@
---
title: 'How to build browser for Windows'
title: 'How To Build Browser For Windows'
---
Many of the build scripts are bash scripts and not natively invokable in Windows. To solve this, you can build the project using Git Bash.

View File

@@ -187,10 +187,19 @@ const sidebars = {
items: [
'Developers/project-layout',
'Developers/releasing',
'Developers/Building-Windows',
'Developers/using-the-API',
'Developers/API',
'Developers/ActualQL',
'Developers/Building-Windows',
{
type: 'category',
label: 'ActualQL',
collapsed: true,
items: [
'Developers/ActualQL/Overview',
'Developers/ActualQL/Functions',
'Developers/ActualQL/Examples',
],
},
],
},
'FAQ',