# How to flatten and remove duplicates in query results?

**URL:** https://community.silverbullet.md/t/how-to-flatten-and-remove-duplicates-in-query-results/3397
**Category:** Lua
**Created:** [October 15, 2025, 7:44pm UTC](https://community.silverbullet.md/t/how-to-flatten-and-remove-duplicates-in-query-results/3397 "2025-10-15T19:44:51Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![thick.cliff](https://community.silverbullet.md/letter_avatar_proxy/v4/letter/t/8e7dd6/32.png) [@thick.cliff](https://community.silverbullet.md/u/thick.cliff)
#### Post date: [October 15, 2025, 7:44pm UTC](https://community.silverbullet.md/t/how-to-flatten-and-remove-duplicates-in-query-results/3397/1 "2025-10-15T19:44:51Z")

</div>

Using the following query I get a list of arrays. I want to flatten these arrays into one array and remove duplicates. Not sure what built in functions are available.

```auto
${query[[
  from index.tag "page"
  where name:startsWith("Journal/")
  select {
    Tags = _.tags
  }
]]}

```

Here is my best failed attempt

```auto
${query[[
  from index.tag "page"
  where name:startsWith("Journal/")
  select {
    Tags = utils.unique(utils.flatten(_.tags))
  }
]]}

-- Flattens a list of lists into a single list
function utils.flatten(list_of_lists)
  local flat = {}
  for _, sublist in ipairs(list_of_lists) do
    for _, value in ipairs(sublist) do
      table.insert(flat, value)
    end
  end
  return flat
end

-- Removes duplicates from a list while preserving order
function utils.unique(list)
  local seen = {}
  local result = {}
  for _, value in ipairs(list) do
    if not seen[value] then
      seen[value] = true
      table.insert(result, value)
    end
  end
  return result
end

```

---

<div class="post-metadata">

### Author: ![markalex](https://community.silverbullet.md/user_avatar/community.silverbullet.md/markalex/32/1861_2.png) [@markalex](https://community.silverbullet.md/u/markalex)
#### Post date: [October 16, 2025, 3:18pm UTC](https://community.silverbullet.md/t/how-to-flatten-and-remove-duplicates-in-query-results/3397/2 "2025-10-16T15:18:43Z")

</div>

In general, I would like to know how to flatten arrays in lua too.

But for a specific usecase similar to yours, I’m using a workaround:

```auto
${query[[
  from index.tag "tag" 
 where _.parent == "page" and page:startsWith("Journal/")
]]}

```

---

<div class="post-metadata">

### Author: ![thick.cliff](https://community.silverbullet.md/letter_avatar_proxy/v4/letter/t/8e7dd6/32.png) [@thick.cliff](https://community.silverbullet.md/u/thick.cliff)
#### Post date: [October 16, 2025, 7:03pm UTC](https://community.silverbullet.md/t/how-to-flatten-and-remove-duplicates-in-query-results/3397/3 "2025-10-16T19:03:04Z")

</div>

> [@markalex](#):
>
> ```auto
> ${query[[
> from index.tag "tag" 
> where _.parent == "page" and page:startsWith("Journal/")
> ]]}
> 
> ```

Thanks, that worked! This is what I ended up with.

```auto
${query[[
  from index.tag "tag"
  where _.parent == "page" and page:startsWith("Journal/") 
  select "[[" .. _.name .. "]]"
]]}

```

Does silverbullet have any documentation about the object model?

---

<div class="post-metadata">

### Author: ![markalex](https://community.silverbullet.md/user_avatar/community.silverbullet.md/markalex/32/1861_2.png) [@markalex](https://community.silverbullet.md/u/markalex)
#### Post date: [October 16, 2025, 7:25pm UTC](https://community.silverbullet.md/t/how-to-flatten-and-remove-duplicates-in-query-results/3397/4 "2025-10-16T19:25:36Z")

</div>

This obviously depends on how you use tags in your instance, but format `"[[" .. _.name .. "]]"` for tags looks a bit odd to me.

In my instance I have a list of tags that are attached to tasks shown like this:

```auto
${template.each(query[[
select {name=_.name}
  from index.tag "tag" 
 where _.parent == "task"
]], template.new[==[#${name}]==])}

```

It ensures that tags are rendered as a tag (with all your custom styling still in place), and link to virtual page also is there.

---

<div class="post-metadata">

### Author: ![thick.cliff](https://community.silverbullet.md/letter_avatar_proxy/v4/letter/t/8e7dd6/32.png) [@thick.cliff](https://community.silverbullet.md/u/thick.cliff)
#### Post date: [October 16, 2025, 10:12pm UTC](https://community.silverbullet.md/t/how-to-flatten-and-remove-duplicates-in-query-results/3397/5 "2025-10-16T22:12:10Z")

</div>

> [@markalex](#):
>
> ```auto
> ${template.each(query[[
> select {name=_.name}
> from index.tag "tag" 
> where _.parent == "task"
> ]], template.new[==[#${name}]==])}
> 
> ```

That’t better than what I did, thanks
