---
title: Advanced Search
description: Search query syntax for instance list filtering
weight: 56
---

> **New / Beta — v3.35**  
> The advanced search syntax replaces the previous simple full-text search. The `RELATED:` keyword is the canonical form; the old lowercase `related:` is still accepted for backward compatibility.

The instance list search bar accepts a rich query language. Queries are evaluated against the **EAV cache** (`data_cache` table), which stores one indexed row per instance × field. The EAV cache must be up to date for field-level searches to return accurate results — refresh it with `cavaliba cache --eav_refresh` after bulk data changes.

All filtering is performed in the database engine. Large schemas (tens of thousands of instances) are safe to search.


## Quick reference

| Pattern | Meaning |
|---|---|
| `paris` | full-text: any field value, keyname, or displayname contains "paris" |
| `city:Paris` | field `city` contains "Paris" (case insensitive) |
| `city:Par*` | field `city` starts with "Par" |
| `city:*aris` | field `city` ends with "aris" |
| `city:*ari*` | field `city` contains "ari" |
| `city:"Le Mans"` | field `city` contains "Le Mans" (space-safe) |
| `pop:>=500` | field `pop` ≥ 500 (numeric) |
| `pop:>500` | field `pop` > 500 |
| `pop:<=500` | field `pop` ≤ 500 |
| `pop:<800` | field `pop` < 800 |
| `mydate:>="2025-06-01"` | field `mydate` ≥ "2025-06-01" (lexicographic) |
| `A AND B` | both A and B must match |
| `A OR B` | A or B must match |
| `NOT A` | A must not match |
| `EXISTS:last_sync` | instance has a non-empty value for field `last_sync` |
| `EMPTY:last_sync` | instance has no value set for field `last_sync` |
| `NOT EMPTY:last_sync` | instance has a non-empty value for field `last_sync` |
| `NOT EXISTS:last_sync` | instance has no value set for field `last_sync` |
| `is_enabled:True` | enabled instances only (meta field) |
| `is_enabled:False` | disabled instances only (meta field) |
| `keyname:par*` | keyname starts with "par" (meta field) |
| `RELATED:SERVER:srv01` | instances referencing `srv01` in schema `SERVER` |


---

## Full-text search

A bare word searches case-insensitively across all EAV field values, the instance `keyname`, and the `displayname`.

```
paris
```

Matches any instance where any field contains "paris", "Paris", "PARIS", etc.

```
nginx
```

Finds servers, apps, services, or any object that mentions "nginx" in any field.


---

## Boolean operators

Use uppercase `AND`, `OR`, `NOT`. Evaluation is left-to-right; no parentheses are supported.

The default connector between consecutive terms (without an explicit operator) is **AND**.

```
Paris AND active
```

Instances containing both "Paris" and "active" somewhere in their fields.

```
Lyon OR Toulouse
```

Instances containing either "Lyon" or "Toulouse" in any field.

```
NOT Paris
```

Instances where no field contains "Paris".

```
NOT Paris AND active
```

Instances that do not contain "Paris" but do contain "active".

```
Paris OR Lyon OR Toulouse OR Bordeaux
```

Any of the four cities, in any field.


---

## Field search

```
field:value
```

Restricts the search to a specific field name. The field name lookup is case-insensitive. The value is matched with `icontains` (case-insensitive substring) by default.

```
city:Paris
city:paris
city:PARIS
```

All three return the same results.

```
status:active
severity:critical
owner:jean
```


### AND / OR on field searches

```
city:Paris AND status:active
```

Active instances located in Paris.

```
country:France OR country:Germany
```

Instances in France or Germany.

```
status:active AND city:Lyon OR city:Paris
```

Evaluated left-to-right: `(status:active AND city:Lyon) OR city:Paris`.

```
NOT status:disabled AND severity:critical
```

Critical instances that are not disabled.


---

## Wildcard search

Append or prepend `*` to restrict how the value is matched.

| Pattern | Django lookup | Example |
|---|---|---|
| `value*` | `istartswith` | `city:Par*` → Paris, Parma, Parthenay |
| `*value` | `iendswith` | `city:*olis` → Annapolis, Minneapolis |
| `*value*` | `icontains` | `city:*ari*` → Paris, Bari, Marie |

```
hostname:web*
```

All instances whose `hostname` field starts with "web".

```
hostname:*-prod
```

All instances whose `hostname` ends with "-prod".

```
tag:*monitoring*
```

Instances tagged with anything containing "monitoring".

```
hostname:web* AND env:production
```

Production web servers.

```
hostname:web* OR hostname:app*
```

Web or app servers.

```
NOT hostname:*-dev
```

Everything that is not a dev server.


---

## Quoted values

Use double or single quotes to search for values that contain spaces. The colon and quotes are part of the token — the tokenizer handles them transparently.

```
city:"Le Mans"
city:'Le Mans'
owner:"Jean Martin"
description:"high availability"
```

Quotes can be combined with wildcards:

```
owner:"Jean*"
```

> **Note:** The POST request validator accepts `"`, `'`, `*`, `>`, `<`, `=`, `-` in addition to standard alphanumeric characters.


---

## Numeric comparisons

Use `>=`, `>`, `<=`, `<` before the value. The EAV value is cast to a float in the database for comparison. Works on `int` and `float` field types.

```
pop:>=1000000
pop:>500
pop:<=100
pop:<50
```

```
score:>=90 AND score:<=100
```

Score between 90 and 100.

```
count:>0 AND status:active
```

Active instances with a non-zero count.

```
disk_gb:>=500 AND disk_gb:<2000
```

Disk between 500 GB and 2 TB.

```
NOT disk_gb:>=1000
```

Instances with disk under 1 TB (or no disk field).


---

## Date and datetime comparisons

Date fields stored in ISO 8601 format (`YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS`) compare correctly with lexicographic ordering.

```
last_sync:>="2025-01-01"
last_sync:<"2026-01-01"
```

Synced during 2025.

```
last_seen:>="2025-06-01" AND last_seen:<"2025-07-01"
```

Seen in June 2025.

```
expiry:<"2026-04-25"
```

Expired before today.

```
NOT last_sync:>="2025-01-01"
```

Instances not synced since 2025 (or never synced — they have no `last_sync` EAV row and will be included).

> Use `EXISTS:last_sync AND NOT last_sync:>="2025-01-01"` to restrict to instances that have a `last_sync` value but it is before 2025.


---

## Existence and emptiness

The EAV cache only stores **non-empty** values. A field with an empty or missing value has no EAV row.

### EXISTS

```
EXISTS:last_sync
```

Instances that have a non-empty value set for `last_sync`.

```
NOT EXISTS:last_sync
```

Instances where `last_sync` is not set (equivalent to `EMPTY:last_sync`).

```
EXISTS:serial_number AND status:active
```

Active instances that have a serial number.

```
EXISTS:last_sync AND last_sync:<"2025-01-01"
```

Instances with a `last_sync` value older than 2025.


### EMPTY

```
EMPTY:last_sync
```

Instances where `last_sync` has no value set (same as `NOT EXISTS:last_sync`).

```
NOT EMPTY:last_sync
```

Instances with a non-empty `last_sync` value (same as `EXISTS:last_sync`).

```
EMPTY:owner AND status:critical
```

Critical instances with no owner assigned.

```
NOT EMPTY:serial_number AND NOT EMPTY:warranty_end
```

Instances that have both a serial number and a warranty end date.


---

## Meta fields

These fields map directly to `DataInstance` columns and bypass the EAV cache entirely, so they are always accurate.

### is_enabled

```
is_enabled:True
is_enabled:False
```

```
is_enabled:False AND severity:critical
```

Disabled critical instances.

```
NOT is_enabled:True
```

Same as `is_enabled:False`.


### keyname

```
keyname:srv-paris-01
keyname:srv*
keyname:*-prod
keyname:*web*
```

```
keyname:web* AND is_enabled:True
```

Enabled instances whose key starts with "web".


### displayname

```
displayname:Paris
displayname:*Server*
displayname:"Main DC"
```


---

## Related instances

The `RELATED:` keyword lists instances of the current schema that reference a specific object in another schema. This filter is also applied automatically when clicking the **Related Objects** badge on an instance detail page.

```
RELATED:<classname>:<keyname>
```

```
RELATED:site:paris-01
```

All instances (in the current schema) that reference `paris-01` from the `site` schema.

```
RELATED:customer:acme-corp
```

All assets assigned to ACME Corp.

> `RELATED:` is a standalone query — it cannot be combined with AND/OR/NOT in the current version.  
> The lowercase form `related:` is still accepted for backward compatibility.


---

## Combining everything — real-world examples

```
hostname:web* AND is_enabled:True AND EXISTS:last_sync
```

Enabled web servers that have been synced at least once.

```
status:critical OR status:warning
```

Instances in a critical or warning state.

```
NOT is_enabled:True AND EMPTY:owner
```

Disabled instances with no owner assigned — good for cleanup.

```
env:production AND NOT EXISTS:backup_policy
```

Production instances missing a backup policy.

```
pop:>=100000 AND country:France
```

French cities with population ≥ 100,000.

```
last_sync:<"2025-01-01" AND is_enabled:True
```

Still-enabled instances not synced since 2025.

```
hostname:*-prod AND disk_gb:>=500 AND EXISTS:backup_policy
```

Large production servers that have a backup policy defined.

```
severity:critical AND NOT EMPTY:assignee AND status:open
```

Open critical tickets already assigned to someone.

```
NOT EXISTS:serial_number OR NOT EXISTS:warranty_end
```

Instances missing either a serial number or a warranty date (for audit).


---

## Limitations

- **EAV cache must be fresh.** Field-level searches (`field:value`, `EXISTS:`, `EMPTY:`, comparisons) depend on the EAV cache. Run `cavaliba cache --eav_refresh` after bulk data changes. The meta fields (`is_enabled`, `keyname`, `displayname`) are always accurate.
- **Instances with no fields** (no EAV rows at all) will not appear in field-level or full-text searches. They are visible only in unfiltered listings.
- **No parentheses.** Complex filters like `(A AND B) OR C` are not supported. Rewrite as `A OR C AND B OR C` or split into multiple searches.
- **`RELATED:` is standalone.** It cannot be combined with AND/OR/NOT. Lowercase `related:` is accepted for backward compatibility.
- **Wildcards at boundaries only.** `city:*par*is*` is treated as `icontains` on `par*is`, not as a multi-anchor glob.
- **Numeric cast errors.** If a non-numeric string is stored in a numeric field and a comparison operator is used, the comparison falls back to lexicographic string ordering.
