[Mastra] Document Vector Search Pre-filters

XMLWordPrintableJSON

    • Type: Improvement
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: ABX
    • None
    • None
    • None
    • None
    • None
    • None

      TL;DR

      Mastra's RAG guide's metadata filtering section only shows pgVector. Add MongoDB as an equal example, explain that MongoDB can apply metadata filters inside its fast vector index for quicker filtered search, and show a minimal snippet of how to enable it.

      Context

      Mastra is a TypeScript framework for building AI agents and RAG apps; MongoDB can be its backend for storage and vector search. MongoDB officially supports the Mastra integration, so the official RAG guide should represent MongoDB as a first-class option. Today it uses pgVector in every example.

      Background

      In a RAG app, documents are stored as vectors (lists of numbers that capture meaning). To answer a question, the app does a vector search — it finds the stored vectors closest to the question. Alongside each vector you can store metadata: extra fields like source, author, date, or category. Metadata filtering narrows the search to only vectors whose metadata matches a condition (e.g., only documents where source = 'article1.txt'). Pre-filtering means applying that condition while the vector search runs, so you only search the relevant subset instead of searching everything and throwing away non-matches afterward — that's faster and more precise.

      The difference between the pgVector and MongoDB stores:

      • pgVector: once you add a metadata filter, it can no longer use its fast index and instead compares the query against every row matching the filter, then sorts and takes the top results. Accurate, but slower as the number of matching rows grows.
      • MongoDB: can apply the metadata filter inside its fast index ("pre-filtering" via filterFields), so it stays fast even while filtering. This is a real advantage on larger datasets. (See the Background section below for the "why".)

      Examples

      MongoDB — applies the filter inside the fast index:

      // 1. Declare which metadata fields you want to pre-filter on
      await mongoVector.createIndex({
        indexName: 'embeddings',
        dimension: 1536,
        filterFields: ['source'], // enables native index pre-filtering
      });
      
      // 2. Query with a filter — it's applied inside the fast vector index
      const results = await mongoVector.query({
        indexName: 'embeddings',
        queryVector: embedding,
        topK: 10,
        filter: { source: 'article1.txt' }, // handled during the fast index search
      });
      

      pgVector — filter is a standard query condition:

      // No pre-filter declaration needed; the filter is a normal query condition.
      const results = await pgVector.query({
        indexName: 'embeddings',
        queryVector: embedding,
        topK: 10,
        filter: { source: 'article1.txt' }, // Postgres skips the fast index here and
                                             // compares every matching row, then sorts
      });
      

      Task

      Update the Metadata Filtering section of the RAG guide.

      Goals:

      1. Represent MongoDB alongside pgVector in this section (not just in the reference docs) — as an equal, first-class example.
      2. Call out MongoDB's pre-filtering advantage in one or two plain sentences: MongoDB applies metadata filters inside its fast vector index (filterFields), keeping search fast while filtering, whereas pgVector falls back to comparing every matching row.
      3. Provide minimal examples for both stores so the difference is visible:

      Acceptance Criteria

      • The Metadata Filtering section on https://mastra.ai/docs/rag/retrieval includes a MongoDB example shown as an equal, first-class option next to all existing pgVector examples.
      • The section states MongoDB's pre-filtering advantage in one or two plain sentences (filters applied inside the fast vector index via filterFields, vs. pgVector comparing every matching row).
      • The MongoDB example shows how to enable pre-filtering, including declaring filterFields in createIndex and passing filter in query.
      • Code examples are valid and consistent with the current @mastra/mongodb and @mastra/pg APIs.

      Additional Details: why pgVector "compares every matching row"

      Here's the reasoning behind that claim, so it can be explained accurately:

      • Vector stores rely on a special fast index that can find the closest vectors without checking every stored item — that's what makes vector search quick at scale (in Postgres these index types are called HNSW and IVFFlat).
      • The catch: that fast index only answers one question — "what are the closest vectors overall?" It has no built-in way to also honor "…but only among rows where source = article1.txt."
      • So when you add a metadata filter, pgVector can't use the fast index and still be sure it returns enough matching results. Instead it does the reliable thing: it takes every row matching the filter, calculates the exact distance to the query for each one, sorts them, and returns the top K. This is fully accurate, but the work grows with the number of matching rows — a filter matching a million rows means a million comparisons. (A regular database index on the metadata field speeds up finding the matching rows, but the vector comparisons are still done one by one.)
      • MongoDB (Atlas Vector Search) is built so the filter can be evaluated inside the fast index — as long as the field was declared in filterFields when the index was created. That's why it keeps its speed while filtering. This is exactly what "pre-filtering" means and the advantage the doc should highlight.

      References

            Assignee:
            Unassigned
            Reporter:
            Raschid Jimenez
            None
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: