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
?name
are 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
:where
clauses:- combine:
- with an implicit top-level
AND
- sequentially from top to bottom
- with an implicit top-level
- apply before the
:find
clause- 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
,:keys
and:where
are 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
?details
and their properties?details-props
- At this point, variable
?details
holds 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
?details
holds 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
?material
appears. - At this point, variable
?details
holds 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
?page
holds 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
?summary
holds 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-props
is 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
?summary
holds less IDs than earlier - thus variable
?page
holds fewer IDs than earlier - thus variable
?details
also 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
?type
appears. - At this point:
- variable
?summary
holds even less IDs (if it was to be used again) - thus variable
?page
holds much fewer IDs - thus variable
?details
shrinks 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