How to query for a unique list of property values

I am looking at using the PARA method, and am tagging blocks and pages with a property value of “area”. Some areas are their own page, and some are not.

For example:

page 1
area:: history
block 1
area:: [[health]]
block 2
area:: [[mathematics]]
block 3
area:: [[health]]

etc…

I want to list all areas.
How would I write a query to return a unique list of areas (property values)?
For example, “history”, “health” and “mathematics”?

Here is an example, but it’s not a unique list of area names:

#+BEGIN_QUERY
{:title [:h2 "All Areas"]
 :query [:find (pull ?b [*])
         :where
         (has-property ?b :area)
]
:table-view? true
}
#+END_QUERY

Any help is much appreciated!

Uses plain text and double brackets is possible, but maybe not the most desirable.

As you see here, those values with double brackets have that in the result set. Now we could totally use a replace function to get rid of them, but I propose a different solution.

In the config file there’s a portion we can use for this.

 ;; By default, property value separated by commas will not be treated as
 ;; page references. You can add properties to enable it.
 ;; E.g. :property/separated-by-commas #{:alias :tags}
  :property/separated-by-commas #{:area}

Filling it out like this, we can then remove the double brackets for the area property while maintaining the linked references.

The result will then look like this.

Here’s the query to make the list, regardless of screenshot.

#+BEGIN_QUERY
{:title [:h3 "Areas"]
 :query [:find ?area
  :where
   [?b :block/properties-text-values ?prop]
   [(get ?prop :area) ?area]
 ]
 :result-transform (fn [r] (sort r))
}
#+END_QUERY

I see I kinda got things mixed up a little, but I think you get the idea.

2 Likes

That is very cool :slight_smile:. The query works for me and pulls a unique list of areas!

I see the double brackets there too. Thank you for the suggestions and proposal on how to remove!

I have a follow-up question for you that you may be able to help with…
Is there a way to keep the brackets, and make the links/list items clickable - either as a list or table view?

We can manipulate the query output and make the links ourselves. This doesn’t work when we keep the brackets though.

#+BEGIN_QUERY
{:title [:h3 "Areas"]
 :query [:find ?area
  :keys area
  :where
   [?b :block/properties-text-values ?prop]
   [(get ?prop :area) ?area]
 ]
 :result-transform (fn [r] (sort r))
 :view (fn [result] (for [r result] 
  [:div [:a 
    {:href (str "#/page/" (get-in r [:area]))} 
    (get-in r [:area])
  ] ]
 ) )
}
#+END_QUERY

I defined the value of ?area from the :find as key area using :keys so that I can then use it in the :view class.
In :view I use hiccup to make a html link for the page.

Alternatively we can pull the page out, but that won’t work with your areas that are plain text, they will not show in the result set anymore.
It’s an issue with mixing two different things together.
By using the config option and no brackets we can make a clickable list at least.

2 Likes

To have the values in the list as links is useful. However, by leaving say value1, value2 on the same line, they form 1 link, which, if clicked on, will create a new page entitled value1, value2, which is not what I would want.

Is it possible to have value1 on its own line and value2 on its own line below?

1 Like

Comes back to the same as mentioned in the other thread.

We would need to first separate out the values before creating links.

My apologies, my comment above yours should have been made in the other page you linked to, so I will continue there.

So, I am using this query to get a list of property values:

#+BEGIN_QUERY
{:title [:h3 "Property values list"]
 :query [:find ?topic
  :where
   [?b :block/properties-text-values ?prop]
   [(get ?prop :topic) ?topic]
 ]
 :result-transform (fn [r] (sort r))
}
#+END_QUERY

However, it is not possible to have it rendered as a label: clicking on the icon gives no result.

I would like a table because then you can have the block and page of each value shown.

What block and page would that be exactly?
If I remember correctly it was for a list of unique values. So if you show the block and page, then the value would no longer be unique.
If you pull the ?b instead of the value, then you will get all blocks with property topic and can make a table of it.
Otherwise I don’t know what you mean.

I got the query shown above from you. If I understand the query, it lists all the properties in use.
Some properties are used once (so far), some more.

I am not sure what you mean by unique in this context. If a property occurs on let’s say 2 pages, is it wrong to want to see which 2 pages?

It lists actually the values, not the properties themselves. At least that is the query you posted.
For the property of topic:: what values have been used.
So maybe there are 3 blocks on the topic of cats. This query only shows cats once, not three times.

1 Like

Ah yes, silly me, I mixed up ‘property’ and ‘value’, no wonder I could not find an answer :blush:
Thanks for putting me back on track.

1 Like

What do you mean by that?
I assume I need to amend this line [?b :block/properties-text-values ?prop], but how?

Change :find ?topic to :find (pull ?b [*])

1 Like

Thank you. Now I understand your earlier comments as to what I was asking did not make sense.
If I want to see a list for the blocks having 1 particular topic value I have to do a simple query {{query (property topic value)}}.

I am still in the process of wrapping my head around properties. I just read mentaloid’s Generate explicit hierarchy out of properties - very impressive.

My workflow is too simple at this stage to use his model, but I have bookmarked it.

1 Like

What if each area has multiple values? such as
areas:: [[area1]] [[area2]]