> For the complete documentation index, see [llms.txt](https://manual.bubble.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manual.bubble.io/help-guides/data/the-database/finding-data.md).

# Finding data

This section covers how to search for data using constraints

{% hint style="info" %}
This article takes a long-form look at how searches in Bubble work.

For a more concise, technical list of settings, constraints, and operators, see our core reference entry on searches.

Reference: [Searching](/core-resources/data/search.md)
{% endhint %}

{% hint style="info" %}
**Dynamic expressions:** This article covers different dynamic expressions. If you're new to dynamic expressions, we recommend reading the article below first.

**Article:** [Dynamic expressions](/help-guides/logic/dynamic-expressions.md)
{% endhint %}

Once you've added and updated data in your database, you'll need a way to find that data and display it around your app. This article covers how searching works, from a basic query to sorting, isolating a single record, and the different data sources you can pull from.

## Doing a search

Whenever you need to find data in the database, you perform a search using the `Do a search for` [data source](#user-content-fn-1)[^1]. This sets up a dynamic query with specific constraints, and Bubble returns all things of that data type that match. You can search for one data type at a time, such as *User*.

Say you want to find all users named John. First, set the *Type of content* to *User*, then pick `Do a search` *for* in the *Data source* dropdown.

Then add a *constraint* that tells Bubble to return only users whose name is John. The result is always a list, even when it contains just one thing.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FsxGyfa9yrtSsmfSHjjsP%2Fsearch-for-john.png?alt=media&amp;token=b89b47ad-3c62-4e14-bee7-4308c9dfea8b" alt=""><figcaption></figcaption></figure>

This is how database queries work at their core: you tell Bubble what kind of data to search for, then give it one or more constraints that each thing in the returned list has to match. You can use a search in all sorts of places:

* To display results on a screen
* As part of a workflow, for example to make changes to one or more things
* As part of a [conditional expression](#user-content-fn-2)[^2]

{% hint style="info" %}
Data sources like *Do a search for* are one of the building blocks of **dynamic expressions**. To read more about working with expressions, see the article below.

**Article:** [Dynamic expressions](/help-guides/logic/dynamic-expressions.md)
{% endhint %}

### Static and dynamic constraints

In the example above, the constraint was a static value: the name John. You can also set a constraint as a *dynamic* value, so it changes based on something in your app.

For example, instead of a fixed name, you could point the constraint at the value of an input field. That lets your users type a name and search the database for matching users.

{% hint style="info" %}
Element data sources using *Do a search for* stay synced with the database in real time. Any change in the database, even one made by another user, shows up in your app right away, with no need to manually refresh the search.

The exception is a search that was initially fetched in a workflow.
{% endhint %}

## Display name

By default, a dynamic expression shows as the expression itself, such as `Do a search for`. You can optionally give it a more descriptive label, like "Search for John". The label doesn't change how the search works, it just helps keep your app organized and easy to review.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FxNdaW9rlC4MfxjkfWINx%2Fdisplay-name.png?alt=media&amp;token=72124fd7-e62d-40cf-9666-c6eca408735a" alt=""><figcaption></figcaption></figure>

To change the display name, click on the expression and edit the field *Display name*.

## Sorting the results

Sometimes you'll want to sort the results a particular way, like showing users alphabetically or tasks by priority or deadline. Sorting is useful both for displaying a list and for finding one specific record. For example, to load the *last* user created in your database, you can sort the list by creation date and then isolate the newest one with the *first item* or *last item* operator, depending on the sort order.

### Sorting on the search directly

You can set the sort order directly when you perform the search.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FaH69iylJIIEgiScT0j2h%2Fsorting-searches.png?alt=media&amp;token=f4a63e7a-df46-4883-860a-0a22b86795dc" alt="A search editor for Users with the Sorting section highlighted, set to sort by last name with descending order set to no."><figcaption><p>Set the sort order in the search itself using the Sorting section. Here, users are sorted by last name in ascending order, since Descending order is set to "no".</p></figcaption></figure>

### Sorting with an operator

In some cases you'll be working with a list that isn't loaded from a search, or you'll need to apply sorting *after* another operator in the expression.

<details>

<summary>Applying sorting as an operator (with examples)</summary>

When you add sorting as an operator instead of on the search itself, the sorting is applied on the list that `Do a search for` returns. In other words, the search runs first and hands back its results, and only then does the *sorted* operator reorder them. The order of operations is what makes this useful: any step that happens between the search and the sort, like filtering, merging, or combining lists, is reflected in the final order. This comes in handy in a few situations:

* **Sorting a merged list.** You combine two searches with `:merged with`, then sort the whole thing. Each search sorts independently, so the combined list needs sorting applied after the merge.
* **Sorting a list stored on a field.** A field that holds a list of things (like a user's list of favorite blog posts) has no search to sort. You sort the list after retrieving it.
* **Sorting another element's data.** When your data source is another repeating group's list rather than a fresh search, sorting happens on that referenced list.
* **Sorting a list that came from an API call.** Data returned by the API Connector isn't a database search, so any ordering has to be applied to the returned list afterward.
* **Sorting after `:intersect with`.** When you narrow two lists down to their shared items, the intersection is a new list that you then sort.
* **Re-sorting a list in a custom state.** If you've stored a list in a custom state, sorting it for display happens after you pull it back out of the state.\
  **Sorting a list built through `:plus item` or `:minus item`.** When you've added or removed individual items from a list, the modified list is sorted afterward.

</details>

For those cases, use the *sorted* operator:

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F7hkSMsjC737U7swne6kn%2Fsorted-operator.png?alt=media&amp;token=52b1b9bb-2502-4baa-8808-70d14f2cf618" alt="A data source expression reading &#x22;Search for John&#x22; with the sorted operator being added from a dropdown of other operators."><figcaption><p>Add the sorted operator to a search by typing "sort" and selecting it from the operator list.</p></figcaption></figure>

## Lists versus single things

Bubble handles database records in two ways: as a single item, or as a list. Understanding this distinction matters, because the two are treated differently. When you [load data into container elements](#user-content-fn-3)[^3], for example, a group expects a single thing, while a [repeating group](/help-guides/design/elements/web-app/containers/repeating-groups.md) or [table](/help-guides/design/elements/web-app/containers/table-elements.md) (web) or mobile lists expects a list.

A search always returns a list, even when only one thing matches. In that case it's a list with a count of one, but it's still a list.

### Loading a single record from a list

When a data source returns a list, like `Do a search for` does, any Bubble element[^4] or operator[^5] that expects a *single* item will flag an error in the [issue tracker](#user-content-fn-6)[^6]. To resolve this, you tell Bubble to load just *one* record from the list by adding an operator to the expression.

<table><thead><tr><th width="148.14453125">Operator</th><th>What it returns</th></tr></thead><tbody><tr><td>First item</td><td>The first item in the list. Which one that is depends on how the list is sorted (by creation date, by default).</td></tr><tr><td>Last item</td><td>The last item in the list. Which one that is depends on how the list is sorted (by creation date, by default).</td></tr><tr><td>Random item</td><td>A <a data-footnote-ref href="#user-content-fn-7">pseudorandom</a> item from the list.</td></tr><tr><td>Item #</td><td>A single item at the index number you specify, such as <em>Item 5</em>. This operator requires you to enter a number.</td></tr></tbody></table>

Combining search constraints with the `first item` operator often gets you to the exact thing you're after. For example, you could search *users* with the *Email* field as a constraint. Since emails are unique, providing an existing user's email address returns the right record. Applying `first item` to that result turns the list into a single thing.

### Turning a single record into a list

Sometimes you'll need to go the other way, turning a single item into a list, even if that list holds only the one record. To do this, use the `converted to list` operator.

This comes up whenever something in your app expects a list but what you have is a single thing.

<details>

<summary>Converting a single record into a list examples</summary>

* **Passing it to an action that expects a list.** Some workflow actions (such as [*Copy a list of things*](/core-resources/actions/data-things.md#copy-a-list-of-things)) take a list of things. If you only have a single record but the action needs a list, converting it lets you pass it through.
* **Setting a list field on another thing.** A field that stores a list of things expects a list value. To save a single record into it, convert it first.
* **Passing a single record to a backend workflow that takes a list.** If a backend workflow's parameter is defined as a list of things, a single record needs converting before you can send it.

</details>

## Other data sources

Searching with *Do a search for* is one way to find data, but not the only one. Depending on what you need, another data source may get you there more directly.

<table><thead><tr><th width="209.79296875">Data source</th><th width="303.43359375">Description</th><th>Returns</th></tr></thead><tbody><tr><td>Do a search for</td><td>Searches the database using constraints.</td><td>A list of things</td></tr><tr><td>Current user</td><td>The user currently using the app.</td><td>One thing</td></tr><tr><td>Current page thing</td><td>The record currently loaded onto the page with the <em>Go to page</em> action.</td><td>One thing</td></tr><tr><td>Get data from page URL</td><td>A thing retrieved from a URL parameter that contains a unique ID.</td><td>One thing</td></tr><tr><td>Thing's X</td><td>A value stored in a field on another thing, such as <em>Current User's Company</em>.</td><td>A list or a single item, depending on the field</td></tr></tbody></table>

## Other ways to learn

<details>

<summary><mark style="color:blue;">Core reference</mark></summary>

* [Searching](/core-resources/data/search.md)

</details>

<details>

<summary><mark style="color:blue;">Video lessons</mark></summary>

* [How to use search constraints](https://youtu.be/gOjGDCJrXYI)
* [How to use the *Do a search for* data source](https://www.youtube.com/watch?v=-2_3kuyOxkw)

</details>

[^1]: A *data source* is the part of an expression that defines where Bubble pulls the data from.

    In this context, the data source is a database search.

[^2]: A conditional expression is a way to ask Bubble a question that returns either true or false.

    You can then use the answer in some kind of logic, such as changing an element's formatting or deciding whether a workflow should run.

[^3]: Container elements such as a group can have a database thing loaded into them.

    This lets each child element reference that data to display content, auto-bind input elements, and use it in workflows.

    **Article:** [The element hierarchy](/help-guides/design/elements/the-element-hierarchy.md) **Article section:** [Loading data into containers](/help-guides/design/elements/web-app/containers.md#loading-data-into-containers)

[^4]: *Elements* are all the things you place on the page, such as containers, input forms, and visual elements like icons and images.

    **Article series:** [Elements](/help-guides/design/elements.md)

[^5]: An *operator* is any step you add to an expression after the data source.

    For example, if you have a list of things and you want to return the first item in that list, the expression might look like this: *`Do a search for:first item`*. Here, the `Do a search for` is the data source and *`first item`* is the operator.

[^6]: The issue tracker is the counter in the upper-right part of the Bubble editor. Whenever there's one or more issue with your app, it shows red text and the number of issues.

[^7]: *Pseudorandomness* means the generated number appears random but is actually produced by a deterministic system.

    To your users it makes no noticeable difference, but it means the number isn't cryptographically secure.
