> For the complete documentation index, see [llms.txt](https://docs.durohub.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.durohub.com/advanced-topics/search-query-syntax.md).

# Search Query Syntax

The Duro search bar supports a structured `key:value` query syntax that lets you build precise filters by typing. Queries are parsed into filter pills that you can further refine visually.

{% hint style="info" %}
This page covers the **manual search syntax** (Normal mode). For AI-powered natural language search, toggle "AI Mode On" in the search bar and type freely. For the programmatic API, see [Searching and Filtering](/advanced-topics/searching-and-filtering.md).
{% endhint %}

## How It Works

1. Type a query like `type:part status:design` in the search bar
2. Press **Enter**
3. Your query is parsed into filter pills on the components page
4. Results update immediately

Multiple filters separated by spaces combine with **AND** logic. You can switch to **Any** (OR) mode using the toggle in the filter pill bar.

***

## Quick Reference

| Key          | Aliases       | Description          | Example                 |
| ------------ | ------------- | -------------------- | ----------------------- |
| `type`       |               | Component type       | `type:part`             |
| `status`     |               | Status name          | `status:design`         |
| `state`      |               | Released or modified | `state:released`        |
| `category`   |               | Category name        | `category:capacitor`    |
| `label`      | `labels`      | Label / tag name     | `labels:"Needs Review"` |
| `cpn`        |               | Part number (CPN)    | `cpn:212-00001`         |
| `name`       |               | Component name       | `name:"Mountain Bike"`  |
| `desc`       | `description` | Description text     | `desc:ceramic`          |
| `created`    | `createdAt`   | Creation date        | `created:>2025-01-01`   |
| `modified`   | `updatedAt`   | Last modified date   | `modified:>2025-01-01`  |
| `createdBy`  |               | Creator name         | `createdBy:dustin`      |
| `modifiedBy` |               | Last modifier name   | `modifiedBy:rachel`     |
| `rev`        | `revision`    | Revision value       | `rev:>A`                |
| `pinned`     |               | Pinned status        | `pinned:true`           |
| `bookmarked` |               | Bookmarked status    | `bookmarked:true`       |
| `attr:`      |               | Attribute value      | `attr:capacitance:>10`  |

Free text without a key prefix searches across name, CPN, and description simultaneously.

Text values support the `*` wildcard for pattern matching (e.g. `cpn:401-*`, `name:*widget*`, or the free-text `401-*`). See [Wildcards](#wildcards).

***

## Operators

| Syntax           | Meaning               | Example                          |
| ---------------- | --------------------- | -------------------------------- |
| `key:value`      | equals                | `status:design`                  |
| `key!:value`     | not equals            | `status!:design`                 |
| `key:val1,val2`  | any of (OR)           | `status:design,prototype`        |
| `key!:val1,val2` | none of               | `modifiedBy!:dustin,yuri`        |
| `key:>value`     | greater than / after  | `created:>2025-01-01`            |
| `key:<value`     | less than / before    | `rev:<C`                         |
| `key:>=value`    | greater than or equal | `attr:weight:>=100`              |
| `key:<=value`    | less than or equal    | `attr:capacitance:<=10`          |
| `key:val1..val2` | range (inclusive)     | `created:2025-01-01..2025-06-01` |

### Quoting

Use double quotes for values that contain spaces:

```
labels:"Needs Review"
name:"Mountain Bike Frame"
```

Commas and colons inside quotes are treated as literal characters:

```
labels:"A, B"        (one label named "A, B", not two labels)
name:"Part: Rev A"   (colon is part of the name)
```

***

## Wildcards

Use `*` as a wildcard to match **zero or more characters** at any position. Wildcards work in free-text searches and in the `name`, `cpn`, `desc`, and `label` keys.

| Query           | Matches                                                         |
| --------------- | --------------------------------------------------------------- |
| `401-*`         | `401-00001`, `401-00002`, `401-WIDGET` (starts with "401-")     |
| `*-00001`       | `ABC-00001`, `401-00001`, `XYZ-00001` (ends with "-00001")      |
| `*401*`         | `ABC401XYZ`, `401-Widget`, `PREFIX-401-SUFFIX` (contains "401") |
| `401-*01`       | starts with "401-" and ends with "01"                           |
| `*401*00*`      | contains "401" then "00", in that order                         |
| `cpn:401-*`     | components whose CPN starts with "401-"                         |
| `name:*widget*` | components with "widget" anywhere in the name                   |
| `labels:*-Beta` | components with a label ending in "-Beta"                       |

### Position

Wildcards can appear anywhere — at the start (prefix), end (suffix), in the middle (internal), or several at once:

```
*00001          (suffix — ends with "00001")
401-*           (prefix — starts with "401-")
401-*01         (internal — starts with "401-", ends with "01")
*401*00*        (multiple)
```

### Wildcards vs. exact match

For the text keys, a value **without** a `*` is matched literally:

* `name:widget` — matches the exact name "widget" (case-insensitive)
* `name:*widget*` — matches any name that **contains** "widget"
* `name:widget*` — matches any name that **starts with** "widget"

`desc:` and free text always search within the content, so `desc:ceramic` already behaves like a "contains" search.

### Escaping

To match a literal asterisk, escape it with a backslash:

```
Part\*Model     (matches the literal name "Part*Model")
```

### Notes

* Consecutive wildcards collapse to one: `401-**01` is treated as `401-*01`.
* Quote values that contain spaces, keeping the wildcards inside the quotes: `name:"*mountain bike*"`.
* Leading wildcards (`*00001`) are supported. They scan more broadly, so they can be slower on large libraries.

***

## Keys in Detail

### type

Filter by component type. Values: `part`, `assembly`, `document`.

```
type:part
type:assembly
type:document
type:part,assembly       (parts OR assemblies)
```

### status

Filter by the component's custom status name. Uses the exact status names configured in your library.

```
status:design
status:production
status!:obsolete         (not in obsolete status)
status:design,prototype  (in design OR prototype)
```

### state

Filter by release state. Values: `released`, `modified`.

```
state:released
state:modified
```

### category

Filter by category name. Uses the exact category names configured in your library.

```
category:capacitor
category:resistor
category!:connector       (not connectors)
category:diode,transistor (diodes OR transistors)
```

### label / labels

Filter by label (tag) name. Uses the exact label names in your library. Supports `*` wildcards to match label names by pattern (see [Wildcards](#wildcards)).

```
label:urgent
labels:"Needs Review"
labels!:deprecated
labels:*-Beta            (labels ending in "-Beta")
```

### cpn

Filter by component part number (CPN). Matches the displayed CPN value. Supports `*` wildcards (see [Wildcards](#wildcards)).

```
cpn:212-00001
cpn:RES-001
cpn:401-*                (CPNs starting with "401-")
cpn:*-00001              (CPNs ending with "-00001")
```

### name

Filter by component name. Without a wildcard, the match is **exact** (case-insensitive). Use `*` wildcards for partial matching (see [Wildcards](#wildcards)).

```
name:LM7805              (exact name "LM7805")
name:"Mountain Bike"     (exact name "Mountain Bike" — quotes for spaces)
name:*widget*            (name contains "widget")
name:LM78*               (name starts with "LM78")
name:"*mountain bike*"   (contains "mountain bike"; wildcards stay inside quotes)
```

### desc / description

Search within component descriptions. Uses full-text search with word stemming (e.g., "capacitor" matches "capacitors"). Also supports `*` wildcards for literal pattern matching (see [Wildcards](#wildcards)).

```
desc:ceramic
description:"high voltage"
desc!:obsolete            (description does not contain "obsolete")
desc:*ceramic*            (description contains the literal string "ceramic")
```

### created / modified

Filter by creation or modification date. Supports comparison operators and ranges.

```
created:>2025-01-01           (created after Jan 1, 2025)
modified:<2025-06-01          (modified before Jun 1, 2025)
created:2025-01-01..2025-06-01  (created between Jan 1 and Jun 1)
modified:>2025-03-01          (modified after Mar 1, 2025)
```

### createdBy / modifiedBy

Filter by the user who created or last modified the component. Matches against user names in your library.

```
createdBy:dustin
modifiedBy:rachel
modifiedBy!:dustin,yuri   (not modified by dustin or yuri)
```

### rev / revision

Filter by revision value. Supports comparison operators for ordering.

```
rev:A
rev:>B           (revisions after B)
rev:<5           (revisions before 5)
rev:A..D         (revisions A through D)
```

### pinned / bookmarked

Filter by pin or bookmark status.

```
pinned:true
pinned:false
bookmarked:true
```

### attr: (Attributes)

Filter by user-defined attribute values. The `attr:` prefix is required to distinguish from built-in keys. Attribute names are matched case-insensitively against your library's configured attributes.

```
attr:capacitance:>10
attr:color:black
attr:weight:>=100
attr:material:steel
attr:cost:<50
```

{% hint style="info" %}
Attribute filters require the component to **have** the attribute. For example, `attr:color!:black` returns components that have a color attribute but where the value is not black. Components without a color attribute are excluded.
{% endhint %}

***

## Free Text Search

Any text without a `key:` prefix is treated as a free-text search across component name, CPN, and description.

```
mountain bike            (searches name, CPN, and description)
LM7805                   (finds by name or CPN match)
ceramic                  (finds in name or description)
```

Free text also supports `*` wildcards, applied across name, CPN, and description (see [Wildcards](#wildcards)):

```
401-*                    (name/CPN/description starting with "401-")
*00001                   (ending with "00001")
*401*                    (containing "401")
```

Free text can be combined with key:value filters:

```
ceramic type:part        (free text "ceramic" AND type is part)
```

***

## Combining Filters

Multiple space-separated filters combine with **AND** logic:

```
type:part status:design modifiedBy:dustin created:>2025-01-01
```

This finds **parts** in **design** status, modified by **dustin**, created **after Jan 1, 2025** — all conditions must match.

After parsing, you can switch to **Any** (OR) mode using the All/Any toggle in the filter pill bar.

***

## Common Scenarios

### Find all parts in a specific status

```
type:part status:design
```

### Find components not modified by a specific user

```
modifiedBy!:john
```

### Find released resistors and capacitors

```
state:released category:resistor,capacitor
```

### Find components modified in the last quarter

```
modified:>2025-01-01
```

### Find components by date range

```
created:2025-01-01..2025-03-31
```

### Find components by description keyword

```
desc:automotive
```

### Find all components in a CPN series (wildcard)

```
cpn:401-*
```

### Find components with a name pattern (wildcard)

```
name:*bracket*
```

### Find parts where an attribute exceeds a threshold

```
type:part attr:capacitance:>100
```

### Find components where color is not black

```
attr:color!:black
```

### Exclude multiple users from results

```
modifiedBy!:dustin,yuri
```

### Find components with a specific revision or higher

```
rev:>B type:part
```

### Find pinned favorites in production

```
pinned:true status:production
```

### Combine free text with structured filters

```
ceramic type:part status:design
```

***

## Error Handling

If a key is unrecognized, the search bar highlights the problematic segment and suggests a correction. For example:

* `weight:100` — suggests `attr:weight:100` (attribute prefix required)
* `foobar:xyz` — shows "Unknown key" error

Partially valid queries still work. If 3 of 4 segments parse successfully, the 3 valid filters are applied and the 1 error is shown.

***

## API Equivalent

The search bar syntax maps to the `buildFilterFromQuery` GraphQL query. API consumers can use this directly:

```graphql
query {
  component {
    buildFilterFromQuery(input: { query: "type:part status:design" }) {
      filterValues {
        field
        comparator
        value
        displayLabel
      }
      filterInput {
        and {
          status { id { eq } }
          category { type { eq } }
        }
      }
      success
      errors {
        segment
        message
        suggestion
      }
    }
  }
}
```

Or execute the search in one call:

```graphql
query {
  component {
    filterWithQuery(input: { query: "type:part status:design", limit: 50 }) {
      components {
        id
        name
      }
      totalCount
      pageInfo {
        hasNextPage
        endCursor
        resultsReturnedCount
      }
      interpretation
    }
  }
}
```

To paginate through results, pass the `endCursor` from the previous page as `after`:

```graphql
query {
  component {
    filterWithQuery(input: {
      query: "type:part status:design"
      limit: 50
      after: "eyJ2IjoiMjAyNi0wMy0yM1..."
    }) {
      components { id name }
      pageInfo { hasNextPage endCursor }
    }
  }
}
```

{% hint style="success" %}
The `filterWithQuery` API accepts the same syntax as the search bar, making it easy to build integrations that mirror the web app's search experience.
{% endhint %}

***

## Next Steps

* [Searching and Filtering API Reference](/advanced-topics/searching-and-filtering.md) — programmatic filtering with the Advanced Filter API and AI search
* [Components](/core-concepts/components.md) — component data model and CRUD operations
* [Authentication](/getting-started/authentication.md) — setting up API access


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.durohub.com/advanced-topics/search-query-syntax.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
