> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyborg.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Metadata Filtering

CyborgDB supports metadata tagging and filtering, enabling fine-grained search filters in addition to encrypted vector search. Metadata, like vectors, are end-to-end encrypted and never exposed in plaintext outside of the client.

## Supported Metadata

The following metadata types are supported:

* Boolean
* String
* List of strings
* Numbers (will be stored as fp64)

## Adding Items with Metadata

To add items with metadata tags, you can pass a dictionary of key-value pairs to the `metadata` field during `upsert`:

<CodeGroup>
  ```python Python icon="python" theme={null}
  # Example data in the format:
  # [{id: str, vector: List[float], metadata: Dict}]
  data = [
      {"id": "item_1", "vector": [0.1, 0.1, 0.1, 0.1], "metadata": {"category": "dog"}},
      {"id": "item_2", "vector": [0.2, 0.2, 0.2, 0.2], "metadata": {"category": "cat"}}
  ]

  # Upsert data with metadata
  index.upsert(data, index_key=index_key)
  ```
</CodeGroup>

This metadata will be encrypted and stored in the index.

<Tip>Metadata field names and string values are **case-sensitive**. Ensure that the metadata field names and values are consistent when filtering queries.</Tip>

## Filtering Queries with Metadata

CyborgDB supports a subset of [MongoDB's Query and Projection Operators](https://www.mongodb.com/docs/manual/reference/operator/query/). For more details, see [Metadata Query Operators](#metadata-query-operators)

To filter a query with metadata, you can pass a dictionary of filters to the `filters` field during `query`:

<CodeGroup>
  ```python Python icon="python" theme={null}
  # Example query
  query_vectors = [0.5, 0.9, 0.2, 0.7]
  top_k = 10

  # Example filters
  filters = {
      "category": {"$in": ["dog", "cat"]} # Will match either 'dog' or 'cat'
  }

  # Perform query
  results = index.query(query_vectors=query_vectors, top_k=top_k, filters=filters, index_key=index_key)
  ```
</CodeGroup>

## Metadata Indexing

By default, all metadata fields are indexed using encrypted indexing, so filters on indexed fields resolve directly from the index and filtered queries stay fast. Filters on fields declared `filterable: False` in the index's [`metadata_schema`](../../python/client/create-index#metadata-schema), and `$regex` / `$contains` on fields not declared `pattern: True`, are instead evaluated on decrypted metadata after retrieval, which is slower.

## Metadata Query Operators

CyborgDB supports a subset of [MongoDB's Query and Projection Operators](https://www.mongodb.com/docs/manual/reference/operator/query/). Specifically, the following operators are supported:

| Filter | Types | Description |
| :-: | :-: | - |
| `$exists` | `any` | Matches vectors that have this field |
| `$eq` | `Boolean`, `Number`, `String` | Matches vectors with the metadata that is equal to the filter value |
| `$ne` | `Boolean`, `Number`, `String` | Matches vectors with the metadata that is not equal to the filter value |
| `$in` | `Number`, `String` | Matches vectors with metadata that is in the filter array |
| `$nin` | `Number`, `String` | Matches vectors with metadata that is not in the filter array |
| `$gt` | `Number` | Matches vectors with metadata that is greater than the filter value |
| `$gte` | `Number` | Matches vectors with metadata that is greater than or equal to the filter value |
| `$lt` | `Number` | Matches vectors with metadata that is less than the filter value |
| `$lte` | `Number` | Matches vectors with metadata that is less than or equal to the filter value |
| `$regex` | `String` | Matches vectors whose metadata string matches the given pattern (see [Regex patterns](#regex-patterns)) |
| `$contains` | `String` | Matches vectors whose metadata string contains the given substring |

### Regex patterns

`$regex` and `$contains` patterns are evaluated by [RE2](https://github.com/google/re2/wiki/Syntax), matched **unanchored** — the same convention as MongoDB's `$regex`. Anchor with `^` and `$` explicitly if you need a full-string match.

RE2 is linear-time and safe against catastrophic-backtracking patterns, but accepts a narrower syntax than PCRE / ECMAScript regex. In particular:

* **Lookahead** and **lookbehind** (`(?=…)`, `(?!…)`, `(?<=…)`, `(?<!…)`) are unsupported.
* **Backreferences** (`\1`, `\2`, …) are unsupported.
* Malformed patterns (e.g. unbalanced groups) raise a validation error.

Any of the above raises `ValueError` at query time — patterns are rejected up front rather than at match time, so a bad pattern fails fast.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.