Lua Integrated Query (LIQ) is a SilverBullet specific Lua extension. It adds a convenient query syntax to the language in a backwards compatible way. It does so by overloading Lua’s default function call + single argument syntax when using `query` as the function call. As a result, Lua programs using LIQ are still syntactically valid Lua. The syntax for LIQ is `query[[my query]]`. In regular Lua `[[my query]]` is just another way of writing `"my query"` (it is an alternative string syntax). Function calls that only take a string argument can omit parentheses, therefore `query[[my query]]` is equivalent to `query("my query")`. However, in [[Space Lua]] it interpreted as an SQL (and [LINQ](https://learn.microsoft.com/en-us/dotnet/csharp/linq/))-inspired integrated query language. General syntax: query[[ from in where order by limit , select ]] LIQ operates on any Lua collection. For instance, to sort a list of numbers in descending order: ${query[[from n = {1, 2, 3} order by n desc]]} However, in most cases you’ll use it in conjunction with [[API/index#index.tag(name)]]. Here’s an example querying the 3 pages that were last modified: ${query[[ from p = index.tag "page" order by p.lastModified desc select p.name limit 3 ]]} Note that the query returns a regular Lua table, so it can be part of a bigger expression: ${some(query[[ from p = index.tag "page" limit 0 ]]) or "Matched no pages"} # Clauses Here are the clauses that are currently supported: ## from The `from` clause specifies the source of your data. There are two syntactic variants: **Recommended:** With explicit variable binding: from v = <> binding each item to the variable `v`. However, there is also the more concise: from <> implicitly binding each item to the variable `_` as well as making all attributes directly available as variables. The latter, while shorter, is less performant and will block future optimizations, so the variable-binding variant is preferred. > **warning** Warning > When you use a `from` clause without explicit variable binding (so without thee `v in` syntax), note that any attribute of the object you’re iterating over will shadow global variables. For instance, if you have an object with a `table` attribute, regular `table` APIs will become inaccessible within the query. > > **Recommendation:** Use the explicit variable binding syntax Example without variable binding: ${query[[from {1, 2, 3} select _]]} With variable binding: ${query[[from n = {1, 2, 3} select n]]} A more realistic example using `index.tag`: ${query[[from p = index.tag "page" order by p.lastModified select p.name limit 3]]} ## where The `where` clause allows you to filter data. When the expression evaluated to a truthy value, the item is included in the result. Example: ${query[[from n = {1, 2, 3, 4, 5} where n > 2]]} Or to select 5 pages tagged with `#meta`: ${query[[from p = index.tag "page" where table.includes(p.tags, "meta") limit 5]]} Or select based on name (including folder) and a [[API/string|string function]] ${query[[from p = index.tag "page" where p.name:startsWith("Person")]]} ## order by [desc] The `order by` clause allows you to sort data, when `desc` is specified it reverts the sort order. As an example, the last 3 modified pages: ${query[[ from p = index.tag "page" order by p.lastModified desc select p.name limit 3 ]]} You can order based on multiple expressions by specifying multiple expressions separated by commas: ${query[[ from p = index.tag "page" order by p.lastModified desc, p.name select p.name limit 3 ]]} Sorting of strings can be adjusted with `queryCollation` in [[^Library/Std/Config]] ## limit [, ] The `limit` clause allows you to limit the number of results, optionally with an offset. Example: ${query[[from {1, 2, 3, 4, 5} limit 3]]} You can also specify an offset to skip some results: ${query[[from {1, 2, 3, 4, 5} limit 3, 2]]} ## select The `select` clause allows you to transform each item in the result set. If omitted, it defaults to returning the item itself. Some examples: Double each number: ${query[[from n = {1, 2, 3} select n * 2]]} It is convenient to combine it with the [[API/table#table.select(table, keys...)]] API: ${query[[ from p = index.tag "page" select table.select(p, "name", "lastModified") limit 3 ]]} ## Rendering the output To render the output as a template, you can rely on the fact that queries return Lua tables. For example, to apply a template to render every page as a link: ${template.each(query[[ from p = index.tag "page" order by p.lastModified desc limit 3 ]], templates.pageItem)} To render pages as links with their full local URL, use `templates.fullPageItem`. For more information on available templates, see [[^Library/Std/Infrastructure/Query Templates]].