Mixedbread

Metadata Filtering

Learn how to filter Store files and search results using powerful metadata queries with logical and comparison operators.

Metadata filtering provides a powerful way to narrow down results based on the metadata attached to your files.

Need to understand metadata types? This page covers filtering syntax and operations. For supported metadata types and structure, see Metadata Types.

Quick Example

Here's a simple example of filtering files by category:

Basic Metadata Filter
from mixedbread import Mixedbread

mxbai = Mixedbread(api_key="YOUR_API_KEY")

response = mxbai.stores.files.list(
    store_identifier="my-knowledge-base",
    limit=10,
    metadata_filter={"key": "category", "value": "documentation", "operator": "eq"},
)

for file in response.data:
    print(file)

Filter Structure

Filters can be structured in two ways depending on your needs:

Single Field Filter (Direct Condition)

For simple single-field filtering, you can use a direct condition:

{"key": "metadata_key", "operator": "comparison", "value": "target_value"}

Example:

{"key": "category", "operator": "eq", "value": "documentation"}

Multiple Field Filter (Logical Operators)

For complex filtering with multiple conditions, use logical operators:

{
  "logical_operator": [
    {"key": "metadata_key", "operator": "comparison", "value": "target_value"}
  ]
}

Example filter structure:

{
  "all": [
    {"key": "category", "operator": "eq", "value": "documentation"}
  ]
}

Generated Metadata Fields

You can target auto-generated chunk metadata by prefixing the key with generated_metadata.. This works the same way as regular metadata filters and is especially useful for filtering on values described in Generated Metadata.

{
  "any": [
    {"key": "generated_metadata.file_type", "operator": "eq", "value": "text/markdown"},
    {"key": "generated_metadata.language", "operator": "eq", "value": "en"}
  ]
}

Use dot notation to drill into nested structures, e.g. generated_metadata.chunk_headings.level.

System Fields

In addition to file metadata and generated metadata, you can filter on a small set of indexed system fields by referencing them directly (without any prefix):

  • file_id — the file the chunk belongs to
  • chunk_index — the position of the chunk within its file
{
  "all": [
    {"key": "file_id", "operator": "eq", "value": "f3c1..."},
    {"key": "chunk_index", "operator": "lt", "value": 10}
  ]
}

This is useful for restricting search to a specific file or to the leading chunks of each file (e.g. titles or introductions).

Logical Operators

Combine multiple conditions using logical operators to create sophisticated filters. Groups can sit side by side in one filter object: all, any and none at the same level must all hold.

All (AND Operation)

All conditions must be true:

{
  "all": [
    {"key": "category", "operator": "eq", "value": "documentation"},
    {"key": "language", "operator": "eq", "value": "python"},
    {"key": "status", "operator": "eq", "value": "published"}
  ]
}

Any (OR Operation)

At least one condition must be true:

{
  "any": [
    {"key": "language", "operator": "eq", "value": "python"},
    {"key": "language", "operator": "eq", "value": "javascript"},
    {"key": "language", "operator": "eq", "value": "typescript"}
  ]
}

None (NOT Operation)

None of the conditions should be true:

{
  "none": [
    {"key": "status", "operator": "eq", "value": "deprecated"},
    {"key": "status", "operator": "eq", "value": "draft"}
  ]
}

Comparison Operators

Equality and Comparison Operators

// Equal to
{"key": "status", "operator": "eq", "value": "published"}

// Not equal to
{"key": "status", "operator": "not_eq", "value": "draft"}

// Greater than
{"key": "priority", "operator": "gt", "value": 5}

// Greater than or equal to
{"key": "created_at", "operator": "gte", "value": "2024-01-01"}

// Less than
{"key": "rating", "operator": "lt", "value": 3.0}

// Less than or equal to
{"key": "rating", "operator": "lte", "value": 4.5}

// Value in list
{"key": "tags", "operator": "in", "value": ["tutorial", "guide"]}

// Value not in list
{"key": "language", "operator": "not_in", "value": ["deprecated", "legacy"]}

// Contains: substring match on a text field (case-sensitive)
{"key": "title", "operator": "contains", "value": "guide"}

// Contains: membership in a list/array field (e.g. a "tags" array that includes "tutorial")
{"key": "tags", "operator": "contains", "value": "tutorial"}

// Regex matching (case-sensitive)
{"key": "title", "operator": "regex", "value": "^red.*$"}

// String starts with (case-sensitive)
{"key": "category", "operator": "starts_with", "value": "/Users"}

// String does not start with: wrap starts_with in a none group
{"none": [{"key": "path", "operator": "starts_with", "value": "/tmp/"}]}

contains vs in: in checks whether a field's value is one of the values you provide (field ∈ [a, b, c]). contains is the reverse — it checks whether the field itself contains the value you provide. On a text field it matches a substring; on a list/array field (such as tags or an acl array) it matches when the array includes that exact element. Both are case-sensitive.

Data Type Filtering

String Values

Case-sensitive by default - ensure consistent casing in your metadata:

// String Values (case-sensitive)
{"key": "category", "operator": "eq", "value": "Documentation"}  // Won't match "documentation"

// Use consistent casing in metadata
{
  "category": "documentation",  // lowercase
  "status": "published",        // lowercase
  "team": "engineering"         // lowercase
}

Numeric Values

Support integer and float comparisons:

// Numeric Values
{"key": "priority", "operator": "gt", "value": 5}
{"key": "score", "operator": "gte", "value": 0.8}

Boolean Values

Support true/false conditions:

// Boolean Values
{"key": "is_public", "operator": "eq", "value": true}
{"key": "deprecated", "operator": "eq", "value": false}

Date Values

Recommend ISO 8601 format:

// Date Values (ISO 8601 format recommended)
{"key": "created_at", "operator": "gte", "value": "2024-01-01"}
{"key": "last_updated", "operator": "lt", "value": "2024-12-31T23:59:59Z"}

Array/List Values

Support membership filtering:

// Array/List Values
{
  "tags": ["tutorial", "python", "web"],
  "authors": ["alice", "bob"]
}

// Filter by array membership
{"key": "tags", "operator": "in", "value": ["tutorial", "guide"]}

Combined Logical Operations

Nested Conditions

Complex multi-level filtering example:

{
  "all": [
    {"key": "category", "operator": "eq", "value": "documentation"},
    {
      "any": [
        {"key": "language", "operator": "eq", "value": "python"},
        {"key": "language", "operator": "eq", "value": "javascript"}
      ]
    }
  ],
  "none": [
    {"key": "status", "operator": "eq", "value": "deprecated"}
  ]
}

Advanced Filtering Example

Here's a practical example demonstrating complex nested filters:

Advanced Metadata Filter
from mixedbread import Mixedbread

mxbai = Mixedbread(api_key="YOUR_API_KEY")

metadata_filter = {
    "all": [
        {"key": "status", "value": "published", "operator": "eq"},
        {
            "any": [
                {"key": "priority", "value": 3, "operator": "gte"},
                {
                    "all": [
                        {"key": "category", "value": "important", "operator": "eq"},
                        {"key": "reviewed", "value": True, "operator": "eq"},
                    ]
                },
            ]
        },
    ]
}

response = mxbai.stores.files.list(
    store_identifier="my-knowledge-base",
    limit=10,
    metadata_filter=metadata_filter,
)

for file in response.data:
    print(file)
Interactive playground that runs preset metadata filters against six sample files. The files are quickstart.md (category documentation, language python, status published, priority 4, reviewed, tags tutorial and python), js-sdk.md (documentation, javascript, draft, priority 2, not reviewed, tag guide), types.md (documentation, typescript, published, priority 1, reviewed, tag reference), security.md (important, python, published, priority 2, reviewed, tag audit), v1-api.md (important, javascript, deprecated, priority 5, not reviewed, tag tutorials) and Setup.md (category "Documentation" with a capital D, python, published, priority 2, not reviewed, tag tutorial). An all group of category eq documentation and an any group of language eq python or javascript matches quickstart.md and js-sdk.md; types.md is typescript and Setup.md fails the case-sensitive category check. The advanced filter, status eq published and either priority gte 3 or an all group of category eq important and reviewed eq true, matches quickstart.md through its priority and security.md through the inner all group; v1-api.md has priority 5 but is deprecated. A none group of status eq deprecated and status eq draft matches every file except js-sdk.md and v1-api.md. language in ["java", "python"] matches the three python files, because in requires the field to equal a listed value, while language contains "java" is a substring match and matches the two javascript files. tags contains "tutorial" matches quickstart.md and Setup.md but not v1-api.md, because array membership needs the exact element. category eq "Documentation" matches only Setup.md, because string matching is case-sensitive.
Preset filter
Filterchecked against quickstart.md
true:{: [true:  {"key": "category", "operator": , "value": "documentation"},true:  {: [true:    {"key": "language", "operator": , "value": "python"},false:    {"key": "language", "operator": , "value": "javascript"}  ]}]}
filestatuspriorityreviewedtags
documentationpythonpublished4truetutorialpython
documentationjavascriptdraft2falseguide
documentationtypescriptpublished1truereference
importantpythonpublished2trueaudit
importantjavascriptdeprecated5falsetutorials
Documentationpythonpublished2falsetutorial
2 of 6 files match. Documentation files in Python or JavaScript; Setup.md fails on its capital D.