More than a couple. Should definitely read much more and practice a lot.
- Nobody grasped the syntax just by guessing.
- The advanced queries doc is merely a starting point.
- Should experiment with simpler queries in tiny test-graphs.
I’m going to answer your individual points in an unprecise but simplified way:
- All parts that look like
?nameare arbitrarily-named variables.- They don’t relate to the page content.
- They apply to a database maintained by Logseq separately from the markdown files.
- They are not built-in, so there cannot be a list of them.
- The names are chosen by the users, the computer doesn’t care.
- Same-named variables represent:
- the same single value at any given time
- but potentially multiple values during the same execution of the same query
- They are not defined, they are placeholders.
- They don’t relate to the page content.
- The
:whereclauses:- combine:
- with an implicit top-level
AND - sequentially from top to bottom
- with an implicit top-level
- apply before the
:findclause- They apply to the entries of the database.
- The first clause filters the whole database, the second clause filters the results of the first clause and so on.
- Technically speaking, all
:find,:keysand:whereare at the same level.- However, they apply in this order:
:where→:find→:keys
- However, they apply in this order:
- They apply to the entries of the database.
- combine:
- Easier reading.
- It is sequential.
- The same results can be achieved in different line-order (and also in multiple ways).
- Different orders (and/or ways) can differ in their performance.
Here is a rough but thorough description of what goes on at a middle level:
- Begin with
:where- Gather (the IDs of) all blocks which have properties.
- This is equivalent to filtering-out all blocks without properties.
- Name those blocks
?detailsand their properties?details-props- At this point, variable
?detailsholds a relatively big number of IDs.
- At this point, variable
- Then keep only those
?details-blocks that have propertymaterial::- And name the value
?material - At this point, variable
?detailsholds less IDs than in the beginning.
- And name the value
- Then keep only if that property’s value is “Aluminium”.
- This clause cannot be placed earlier than where the variable
?materialappears. - At this point, variable
?detailsholds even less IDs than in the beginning.
- This clause cannot be placed earlier than where the variable
- Then gather all (the IDs of) the pages that contain the blocks with
?details-IDs.- Name those pages
?page - At this point, variable
?pageholds relatively many IDs.- But not more than the number of
?details-blocks.
- But not more than the number of
- Name those pages
- Then keep only the
?page-pages that have blocks.- They all have, because they already contain
?details-blocks. - We still need to do this step, in order to consider all other blocks in
?page-pages.- Name those blocks
?summary- At this point:
- variable
?summaryholds a relatively big number of IDs. ?details-blocks is a subset of?summary-blocks- because although they both belong to the same
?page-pages:?details-blocks got further filtered by property- while
?summary-blocks are not filtered yet
- because although they both belong to the same
- variable
- At this point:
- Name those blocks
- Alternatively, it is possible to:
- begin with
?summary-blocks and deal with?details-blocks later- The relative performance of that approach depends on the actual graph.
- move the two
[?... :block/page ?page]clauses to the bottom- That would be less performant.
- even swap the two
[?... :block/page ?page]clauses with each-other- That would be worse, though fully valid.
- begin with
- They all have, because they already contain
- Then from
?page-pages keep only the ones that contain blocks with properties.- They all do, because they already contain
?details-blocks. - We still need to do this step, in order to consider all other blocks with properties.
- Name those properties
?summary-props- At this point,
?details-propsis a subset of?summary-props
- At this point,
- Name those properties
- They all do, because they already contain
- Then keep only those that have property
type::- And name the value
?type - At this point:
- variable
?summaryholds less IDs than earlier - thus variable
?pageholds fewer IDs than earlier - thus variable
?detailsalso shrinks (if it was to be used again)
- variable
- And name the value
- Then keep only if that property’s value is “Product”.
- This clause cannot be placed earlier than where the variable
?typeappears. - At this point:
- variable
?summaryholds even less IDs (if it was to be used again) - thus variable
?pageholds much fewer IDs - thus variable
?detailsshrinks further (if it was to be used again)
- variable
- This clause cannot be placed earlier than where the variable
- Gather (the IDs of) all blocks which have properties.
- Continue with
:find- Return all the fields of the remaining
?page-pages. - If no pages remain, return nothing.
- Return all the fields of the remaining