Operate in Production
Search
Full-text search with PostgreSQL FTS and pgvector embeddings.
QUESTPIE supports full-text search using PostgreSQL's built-in FTS capabilities and optional embedding-based semantic search with pgvector.
Currently, PostgreSQL FTS and pgvector are the only implemented search adapters. External services like Meilisearch or Elasticsearch are not yet supported.
Making Collections Searchable
Add .searchable() to index a collection for full-text search:
src/questpie/server/collections/posts.ts
import { collection } from "#questpie/factories"
export default collection("posts")
.fields(({ f }) => ({
title: f.text(255).required(),
body: f.textarea(),
tags: f.text(500),
}))
.searchable({
content: (record) => `${record.title} ${record.body ?? ""} ${record.tags ?? ""}`,
metadata: (record) => ({
published: record.status === "published",
}),
})| Option | Type | Description |
|---|---|---|
content | (record) => string | Extracts plain text for full-text indexing. Called on create/update. |
metadata | (record) => object | Structured metadata for faceted filtering. |
How It Works
When a record is created or updated:
- The
contentfunction extracts plain text from the record - PostgreSQL generates a
tsvectorfor the text using the configured language - A GIN index enables fast full-text queries
- BM25 ranking orders results by relevance
Client Search
const results = await client.search.search({
query: "haircut styles",
collections: ["posts", "services"],
limit: 20,
})Search Options
| Option | Type | Description |
|---|---|---|
query | string | Search query (supports PostgreSQL tsquery syntax) |
collections | string[] | Limit search to specific collections |
limit | number | Maximum results (default: 50) |
Server-Side Search
From routes or hooks:
handler: async ({ search }) => {
const results = await search.search({
query: "booking confirmation",
collections: ["posts"],
})
return results
}Embedding-Based Search (pgvector)
For semantic search using vector embeddings:
.searchable({
content: (record) => record.title + " " + record.body,
embeddings: {
enabled: true,
dimensions: 1536,
model: "text-embedding-3-small",
},
})This stores vector embeddings alongside the text index, enabling similarity-based queries that understand meaning rather than just keywords.
Related Pages
- Collections — Data modeling
- Querying — Query operators