ormDB

Full-Text Search in ormDB

Use ormDB's built-in BM25 full-text search for ranked keyword queries. No external search engine required -- search is native to the database.

Difficulty: beginnerTime: 10 minutes

ormDB is a relational database engine written in Rust that replaces PostgreSQL, MySQL, and SQLite. Full-text search is built directly into the engine using BM25 ranking, the same algorithm used by major search engines. There is no external search service to deploy, sync, or maintain.

Your application data and search index live in the same database, unlike PostgreSQL where you might need Elasticsearch as a separate service. When a record is inserted or updated, the search index updates within the same ACID transaction. There is no replication lag, no sync job, and no stale results.

Defining Searchable Fields

Mark fields as searchable in your entity definition:

entity Article {
  id: uuid @primary
  title: text @searchable(weight: 2.0)
  body: text @searchable(weight: 1.0)
  summary: text @searchable(weight: 1.5)
  status: text
  author_id: uuid @relation(User)
  created_at: timestamp
}

The @searchable annotation creates a full-text index on the field. The weight parameter controls how much matches in that field contribute to the relevance score. Title matches score twice as high as body matches.

Searching

Run a full-text search query:

const results = await db.search('Article', {
  query: 'graph database performance',
  where: { status: 'published' },
  limit: 20,
})

Results are ranked by BM25 relevance score. The where clause filters before ranking, so you only search within published articles.

Each result includes the entity data and a relevance score:

{
  records: [
    {
      id: 'article_042',
      title: 'Graph Database Performance Patterns',
      body: '...',
      score: 12.45,
    },
    // ...
  ],
  total: 847,
}

Search with Graph Fetch

Combine search with graph fetches for rich results:

const results = await db.search('Article', {
  query: 'migration safety',
  where: { status: 'published' },
  limit: 10,
  include: {
    author: {
      fields: ['id', 'name', 'avatar_url'],
    },
    tags: true,
  },
})

This finds the 10 most relevant published articles matching “migration safety” and includes each article’s author and tags. One request, one round-trip.

Advanced Search Features

Phrase Matching

Search for exact phrases:

const results = await db.search('Article', {
  query: '"zero-copy wire protocol"',
  limit: 10,
})

Target specific fields:

const results = await db.search('Article', {
  query: 'title:performance body:optimization',
  limit: 10,
})

Highlighting

Get highlighted snippets showing where matches occurred:

const results = await db.search('Article', {
  query: 'graph fetch queries',
  limit: 10,
  highlight: {
    fields: ['title', 'body'],
    pre_tag: '<mark>',
    post_tag: '</mark>',
  },
})

Transactional Consistency

The full-text index is updated within the same ACID transaction as the data write. When you insert an article and immediately search for it, the article appears in results. There is no eventual consistency delay. This is a fundamental advantage over architectures that replicate data from a primary database to a separate search engine. This makes ormDB well-suited for content management and e-commerce use cases.

Full-text search in ormDB is not a replacement for dedicated search infrastructure at massive scale. It is the right tool when your search needs live alongside your application data and you want one fewer service to operate. For AI-powered semantic search, combine full-text search with vector search. For location-aware results, add geographic search filters.

Frequently Asked Questions

How does ormDB's full-text search compare to Elasticsearch?

ormDB's full-text search uses BM25 ranking and is built into the database engine. It is designed for application search workloads where your data already lives in ormDB. Elasticsearch is a dedicated search engine suited for large-scale log analytics and complex search pipelines. For most application search needs, ormDB's native search eliminates the need for a separate service.

What languages are supported for text analysis?

ormDB includes tokenizers and stemmers for major languages including English, Spanish, French, German, Portuguese, Italian, Dutch, and more. Custom tokenizer configurations are supported for specialized use cases.

Can I combine full-text search with graph fetches?

Yes. Full-text search can be the entry point for a graph fetch. Search for articles matching a query and include their authors, tags, and comments in a single round-trip.

Does full-text search work with RLS policies?

Yes. Row-level security policies are applied to full-text search results. Users only see search results for records they are authorized to access.

Can I boost certain fields over others?

Yes. Field weights let you rank title matches higher than body matches, or boost recent documents over older ones. Weights are specified in the search query.

Related Content

Try ormDB today

Open source, MIT licensed. Install and start building.