Facetting (also called faceted search or faceted navigation) is a technique that allows users to narrow down search results by applying structured filters based on metadata attributes. In the context of AI-powered search systems, facetting bridges the gap between freeform semantic queries and precise, structured filtering — enabling users to say “find me documents about hotel amenities” while simultaneously restricting results to a specific property, region, or date range.
Traditional faceted search has powered e-commerce sites for decades (think filtering Amazon results by brand, price, and star rating). In modern vector search systems, facetting takes on new importance because pure semantic similarity search can return conceptually related but contextually irrelevant results. A query about “pool maintenance schedules” might surface documents about pools at properties the user doesn’t manage. Metadata filters — facets — solve this by constraining the semantic search space to only the documents that match real-world business criteria.
For AI engineering teams building retrieval pipelines, facetting is not optional — it’s the mechanism that transforms a general-purpose vector search into a production-grade, multi-tenant, context-aware retrieval system. Without it, you cannot scope queries to specific customers, date ranges, document types, or access control levels.
Facetting depends entirely on metadata that was extracted and attached to documents during the ETL phase. When a document is ingested, alongside its vector embedding, structured attributes are stored as metadata fields. These might include:
property_id — which hotel or venue the document belongs todocument_type — “FAQ”, “manual”, “brochure”, “menu”language — “en”, “es”, “fr”last_updated — timestamp for freshness filteringaccess_level — “public”, “staff-only”, “admin”The quality and completeness of your metadata directly determines the power of your facets. If the ETL pipeline doesn’t extract property_id, you cannot filter by property — no matter how good the vector search is.
Facets are only as good as the metadata extracted during ingestion. A vector database cannot filter on attributes it doesn’t have. Metadata enrichment in the ETL phase is the prerequisite for effective faceted search.
When combining vector similarity search with metadata filters, the system must decide when to apply the filter. There are two fundamental strategies:
Pre-filtering constructs an “allow list” of document IDs that match the metadata criteria before the vector search begins. The ANN (approximate nearest neighbor) algorithm then only considers vectors from this allowed set. This approach is more efficient when the filter is selective (e.g., only 5% of documents match), because the vector index traverses far fewer candidates.
Post-filtering runs the full vector search first, retrieves the top-N most similar results, and then removes any that don’t match the metadata filter. This is simpler to implement but has a critical flaw: if many top results are filtered out, you may end up with far fewer results than requested — or even zero results.
Pre-filtering: Filter first, then search the reduced set. More efficient for selective filters but harder to implement with ANN indexes.
Post-filtering: Search first, then remove non-matching results. Simple but can return too few results when filters are restrictive.
Modern vector databases have developed sophisticated approaches to filtered search:
Beyond filtering, faceted search systems also perform aggregation — counting how many results exist for each facet value. When a user searches for “spa services,” the UI might display:
Document Type: FAQ (12) | Menu (8) | Brochure (4)
Property: Resort A (15) | Hotel B (6) | Hotel C (3)
Language: English (20) | Spanish (3) | French (1)
These counts help users understand the result distribution and make informed filtering decisions. In vector databases, aggregation queries require scanning metadata across the result set, which adds computational overhead but dramatically improves user experience.
Most vector databases support filter expressions that combine multiple conditions. Here’s an example using Weaviate’s GraphQL syntax:
{
Get {
Document(
nearText: { concepts: ["pool maintenance schedule"] }
where: {
operator: And
operands: [
{
path: ["property_id"]
operator: Equal
valueText: "resort_123"
},
{
path: ["document_type"]
operator: Equal
valueText: "manual"
},
{
path: ["last_updated"]
operator: GreaterThan
valueDate: "2025-01-01T00:00:00Z"
}
]
}
) {
title
content
_additional { distance }
}
}
}
This query finds documents semantically similar to “pool maintenance schedule” that are also from a specific property, classified as manuals, and updated within the last year.
In any SaaS platform serving multiple customers, facetting on tenant_id or property_id is the primary mechanism for data isolation. When a hotel staff member asks the AI assistant a question, the retrieval pipeline must filter to only that property’s documents — returning information about a competitor’s property would be a critical failure. This is effectively a security boundary implemented through metadata filtering.
Facets can enforce role-based access control at the retrieval level. Documents tagged with access_level: "admin" are automatically excluded from queries by non-admin users. This prevents the AI from surfacing confidential financial reports or internal memos to unauthorized users, even if those documents are semantically relevant to the query.
Many knowledge bases contain outdated information alongside current data. Facetting on last_updated or effective_date ensures the retrieval pipeline prioritizes recent, accurate information. A query about “breakfast hours” should return the current schedule, not one from three years ago that happens to have a slightly higher similarity score.
Different query intents map to different document types. A question about “how to reset the WiFi password” should preferentially search FAQs and troubleshooting guides, while “what events are happening this weekend” should search event calendars and activity schedules. Facetting on document_type enables this routing without building separate indexes for each type.
For multilingual deployments, filtering by language ensures that a Spanish-speaking user receives Spanish documents, even though the cross-lingual embedding model might rank an excellent English document higher by pure similarity.