DocsReferenceRAGMetadata Filters

Metadata Filters

Mastra provides a unified metadata filtering syntax across all vector stores, based on MongoDB/Sift query syntax. Each vector store translates these filters into their native format.

Basic Example

import { PgVector } from '@mastra/pg';
 
const store = new PgVector(connectionString);
 
const results = await store.query(
  "my_index",
  queryVector,
  10,
  {
    category: "electronics",  // Simple equality
    price: { $gt: 100 },     // Numeric comparison
    tags: { $in: ["sale", "new"] }  // Array membership
  }
);

Supported Operators

Basic Comparison

OperatorDescriptionExampleSupported By
$eqMatches values equal to specified value
{
  age: {
    $eq: 25
  }
}
All
$neMatches values not equal
{
  status: {
    $ne: 'inactive'
  }
}
All
$gtGreater than
{
  price: {
    $gt: 100
  }
}
All
$gteGreater than or equal
{
  rating: {
    $gte: 4.5
  }
}
All
$ltLess than
{
  stock: {
    $lt: 20
  }
}
All
$lteLess than or equal
{
  priority: {
    $lte: 3
  }
}
All

Array Operators

OperatorDescriptionExampleSupported By
$inMatches any value in array
{
  category: {
    $in: ["A", "B"]
  }
}
All
$ninMatches none of the values
{
  status: {
    $nin: ["deleted", "archived"]
  }
}
All
$allMatches arrays containing all elements
{
  tags: {
    $all: ["urgent", "high"]
  }
}
AstraPineconeUpstash
$elemMatchMatches array elements meeting criteria
{
  scores: {
    $elemMatch
  }
}
LibSQLPgVector

Logical Operators

OperatorDescriptionExampleSupported By
$andLogical AND
{
  $and: [
    { price: { $gt: 100 } },
    { stock: { $gt: 0 } } }
  ]
}
All except Vectorize
$orLogical OR
{
  $or: [
    { status: "active" },
    { priority: "high" } }
  ]
}
All except Vectorize
$notLogical NOT
{
  price: {
    $not
  }
}
AstraQdrantUpstashPgVectorLibSQL
$norLogical NOR
{
  $nor: [
    { status: "deleted" },
    { archived: true } }
  ]
}
QdrantUpstashPgVectorLibSQL

Element Operators

OperatorDescriptionExampleSupported By
$existsMatches documents with field
{
  rating: {
    $exists: true
  }
}
All except Vectorize, Chroma

Custom Operators

OperatorDescriptionExampleSupported By
$containsText contains substring
{
  description: {
    $contains: "sale"
  }
}
UpstashLibSQLPgVector
$regexRegular expression match
{
  name: {
    $regex: "^test"
  }
}
QdrantPgVectorUpstash
$sizeArray length check
{
  tags: {
    $size
  }
}
AstraLibSQLPgVector
$geoGeospatial query
{
  location: {
    $geo
  }
}
Qdrant
$datetimeDatetime range query
{
  created: {
    $datetime
  }
}
Qdrant
$hasIdVector ID existence check
{
  $hasId: [
    { "id1", "id2" }
  ]
}
Qdrant
$hasVectorVector existence check
{
  $hasVector: true
}
Qdrant

Common Rules and Restrictions

  1. Field names cannot:

    • Contain dots (.) unless referring to nested fields
    • Start with $ or contain null characters
    • Be empty strings
  2. Values must be:

    • Valid JSON types (string, number, boolean, object, array)
    • Not undefined
    • Properly typed for the operator (e.g., numbers for numeric comparisons)
  3. Logical operators:

    • Must contain valid conditions
    • Cannot be empty
    • Must be properly nested
    • Can only be used at top level or nested within other logical operators
    • Cannot be used at field level or nested inside a field
    • Cannot be used inside an operator
    • Valid: { "$and": [{ "field": { "$gt": 100 } }] }
    • Valid: { "$or": [{ "$and": [{ "field": { "$gt": 100 } }] }] }
    • Invalid: { "field": { "$and": [{ "$gt": 100 }] } }
    • Invalid: { "field": { "$gt": { "$and": [{...}] } } }
  4. $not operator:

    • Must be an object
    • Cannot be empty
    • Can be used at field level or top level
    • Valid: { "$not": { "field": "value" } }
    • Valid: { "field": { "$not": { "$eq": "value" } } }
  5. Operator nesting:

    • Logical operators must contain field conditions, not direct operators
    • Valid: { "$and": [{ "field": { "$gt": 100 } }] }
    • Invalid: { "$and": [{ "$gt": 100 }] }

Store-Specific Notes

Astra

  • Nested field queries are supported using dot notation
  • Array fields must be explicitly defined as arrays in the metadata
  • Metadata values are case-sensitive

ChromaDB

  • Where filters only return results where the filtered field exists in metadata
  • Empty metadata fields are not included in filter results
  • Metadata fields must be present for negative matches (e.g., $ne won’t match documents missing the field)

Cloudflare Vectorize

  • Requires explicit metadata indexing before filtering can be used
  • Use createMetadataIndex() to index fields you want to filter on
  • Up to 10 metadata indexes per Vectorize index
  • String values are indexed up to first 64 bytes (truncated on UTF-8 boundaries)
  • Number values use float64 precision
  • Filter JSON must be under 2048 bytes
  • Field names cannot contain dots (.) or start with $
  • Field names limited to 512 characters
  • Vectors must be re-upserted after creating new metadata indexes to be included in filtered results
  • Range queries may have reduced accuracy with very large datasets (~10M+ vectors)

LibSQL

  • Supports nested object queries with dot notation
  • Array fields are validated to ensure they contain valid JSON arrays
  • Numeric comparisons maintain proper type handling
  • Empty arrays in conditions are handled gracefully
  • Metadata is stored in a JSONB column for efficient querying

PgVector

  • Full support for PostgreSQL’s native JSON querying capabilities
  • Efficient handling of array operations using native array functions
  • Proper type handling for numbers, strings, and booleans
  • Nested field queries use PostgreSQL’s JSON path syntax internally
  • Metadata is stored in a JSONB column for efficient indexing

Pinecone

  • Metadata field names are limited to 512 characters
  • Numeric values must be within the range of ±1e38
  • Arrays in metadata are limited to 64KB total size
  • Nested objects are flattened with dot notation
  • Metadata updates replace the entire metadata object

Qdrant

  • Supports advanced filtering with nested conditions
  • Payload (metadata) fields must be explicitly indexed for filtering
  • Efficient handling of geo-spatial queries
  • Special handling for null and empty values
  • Vector-specific filtering capabilities
  • Datetime values must be in RFC 3339 format

Upstash

  • 512-character limit for metadata field keys
  • Query size is limited (avoid large IN clauses)
  • No support for null/undefined values in filters
  • Translates to SQL-like syntax internally
  • Case-sensitive string comparisons
  • Metadata updates are atomic