# Can I query all existing values of a given property?

**URL:** <https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608>\
**Category:** Requests\
**Created:** [October 8, 2024, 10:18am UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608 "2024-10-08T10:18:13Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![lyndhurst](https://avatars.discourse-cdn.com/v4/letter/l/91b2a8/32.png) [@lyndhurst](https://org-roam.discourse.group/u/lyndhurst)\
**Post date:** [October 8, 2024, 10:18am UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/1 "2024-10-08T10:18:14Z")

</div>

I have a custom property called AREA, and I would like to retrieve a list of all exisiting values in the database. I have no idea how to do it with a simple query.

All I would be able to do is query all the nodes (level 0 is enough in that particular case), and process this list to extract AREA unique values using `assoc-string` I think.

This strategy feels very expensive to me, so I was wondering if it was posible to achieve the same results using `org-roam-db-query`. I recently installed `vulpea`, and started experimenting with it, so I would be very happy with an alternative solution using `vulpea` capabilities.

Thanks for your time.

---

<div class="post-metadata">

**Author:** ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)\
**Post date:** [October 8, 2024, 11:25am UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/2 "2024-10-08T11:25:31Z")

</div>

Is this one-off retrieval, or in every Emacs session or command call?

If you need the list frequently, I’d do a query like this below (replace GEO with AREA — for your purpose, you don’t need to retrieve the ID either), dedupe the same occurrences, and keep the resultant list in a simple list variable.

Or I retrieve the list once, and manually create a list variable in init so that you can manually add/remove from it.

```auto
LAT and LON are decimal degrees of type number (not string)."
  (let ((nodes (org-roam-db-query
                [:select [properties id]
:from nodes
:where (like properties '"%geo%")])))

```

source: [How to use location in org-roam? - #3 by nobiot](https://org-roam.discourse.group/t/how-to-use-location-in-org-roam/3159/3)

---

<div class="post-metadata">

**Author:** ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)\
**Post date:** [October 8, 2024, 11:27am UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/3 "2024-10-08T11:27:37Z")

</div>

I’d dedupe outside the sql, just to be clear, unless you know how in sql (probably UNIQUE can be used…)

---

<div class="post-metadata">

**Author:** ![lyndhurst](https://avatars.discourse-cdn.com/v4/letter/l/91b2a8/32.png) [@lyndhurst](https://org-roam.discourse.group/u/lyndhurst)\
**Post date:** [October 8, 2024, 11:35am UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/4 "2024-10-08T11:35:14Z")

</div>

Thanks for the code.  
In my case, every single node in the database has an AREA property, so if I am not mistaken, this snippet would retrieve all my nodes.  
To answer your previous question, it is a command call I would not use very often. It would be used in a `complete-read` prompt when needing to fix metadata and maybe some specific instances of note creation.

---

<div class="post-metadata">

**Author:** ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)\
**Post date:** [October 8, 2024, 11:48am UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/5 "2024-10-08T11:48:33Z")

</div>

Then I’d retrieve from every node and keep the deduped list as a variable. I don’t see any issue here. What’s your concern ? In fact, I’d list them manually — I am assuming you want to use sql just to be exhaustive.

---

<div class="post-metadata">

**Author:** ![lyndhurst](https://avatars.discourse-cdn.com/v4/letter/l/91b2a8/32.png) [@lyndhurst](https://org-roam.discourse.group/u/lyndhurst)\
**Post date:** [October 8, 2024, 12:27pm UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/6 "2024-10-08T12:27:17Z")

</div>

There is no real issue here, you are right. I should be able to extract the values from nodes, and dedup them. I just wanted to check first if something like `SELECT DISTINCT properties.areas FROM nodes` was possible, and maybe more performant, or simpler code wise.

I have written a lot of overly complicated Elisp functions over the last few months to find out later I was simply reinventing the wheel (and a lesser version of the wheel on top of it all !). Since I am not very comfortable with `org-roam-db-query`, I decided to ask if the db could be queried that way.

Anyway, I think it could be possible with the `vulpea` [db extension](https://github.com/d12frosted/vulpea?tab=readme-ov-file#extending-database) feature, but I am gonna try the Elisp loop approach first to see how fast (or slow) it is.

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)\
**Post date:** [October 8, 2024, 2:01pm UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/7 "2024-10-08T14:01:08Z")

</div>

> [@lyndhurst](#):
>
> `SELECT DISTINCT properties.areas FROM nodes` was possible, and maybe more performant, or simpler code wise

Did you try this? I thought this was possible — and yes it is DISTINCT not UNIQUE. Will try later at home myself.

For deduping, you can use loop if you like but there is also a dedupe function, `delete-dups`.

---

<div class="post-metadata">

**Author:** ![lyndhurst](https://avatars.discourse-cdn.com/v4/letter/l/91b2a8/32.png) [@lyndhurst](https://org-roam.discourse.group/u/lyndhurst)\
**Post date:** [October 8, 2024, 2:34pm UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/8 "2024-10-08T14:34:05Z")

</div>

> [@nobiot](#):
>
> Did you try this? I thought this was possible — and yes it is DISTINCT not UNIQUE. Will try later at home myself.

I tried without the DISTINCT statement this morning, it returned the litteral value ‘properties.area’ for each node in my database 🙂

I have not been very successful at querying properties in general with org-roam, I forgot about my previous attempts, but I came to the understanding that properties where stored as a ‘stringified’ `plist`, so I simply started thinking about it differently.

I went back to the `vulpea` project page a week ago, and my understanding of org-roam and Elisp is finally enough to understand what I read there, and it is a great library. To be honest I thought the author created the `meta` KEY VAL pairs in part for this reason. There is actually a section about the rationale behind the author’s choice, I do not remember it exactly as I write, so do not take my word for it.

> [@nobiot](#):
>
> For deduping, you can use loop if you like but there is also a dedupe function, `delete-dups`.

Thanks for the tip, I forgot about that one, but I think I would have found it back. I believe I will still have to loop over the nodes, extract the AREA values into a list, then, dedupe this list. I have not gotten to it seriously yet…

---

<div class="post-metadata">

**Author:** ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)\
**Post date:** [October 8, 2024, 4:00pm UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/9 "2024-10-08T16:00:28Z")

</div>

OK, I see what you mean now that I’ve tried it myself. The output from `org-roam-db-query` on properties in the nodes table is not intuitive.

Could I suggest you to try the following code?

This `mapcar` form should give you a list of all your areas from all your nodes in string, so you will have duplicates in it.

```emacs-lisp
(mapcar
 (lambda (item)
   (cdr (assoc "AREA" (car item))))
 (org-roam-db-query [:select [properties] :from nodes]))

```

If this works on your end as it does on mine, then it would be a simple operation to dedupe the list, like so:

```emacs-lisp
(delete-dups
 (mapcar
  (lambda (item)
    (cdr (assoc "AREA" (car item))))
  (org-roam-db-query [:select [properties] :from nodes])))

```

`delete-dups` uses `equal` to check duplicate items, so it should work on strings (on my casual test, it works).

---

<div class="post-metadata">

**Author:** ![lyndhurst](https://avatars.discourse-cdn.com/v4/letter/l/91b2a8/32.png) [@lyndhurst](https://org-roam.discourse.group/u/lyndhurst)\
**Post date:** [October 8, 2024, 4:15pm UTC](https://org-roam.discourse.group/t/can-i-query-all-existing-values-of-a-given-property/3608/10 "2024-10-08T16:15:23Z")

</div>

> [@nobiot](#):
>
> ```auto
> (delete-dups
> (mapcar
> (lambda (item)
> (cdr (assoc "AREA" (car item))))
> (org-roam-db-query [:select [properties] :from nodes])))
> 
> ```

I just tried it, it works great, it is fast, and the code is clear. I am going to reuse this logic for a few other ideas I wanted to implement.

Thanks for sharing your solution 👍
