Overview
The $text operator enables full-text search across node fields, supporting pattern matching, case-insensitive searches, and regular expressions.
For advanced text search capabilities with indexing, enable the Inverted Index module (ii: true) during database initialization.
Basic Text Search
Simple Text Match
// Find nodes containing "javascript"
const { results } = await db.map({
query: {
name: { $text: "javascript" }
}
})
Case-Insensitive Search
// Search is case-insensitive by default
const { results } = await db.map({
query: {
type: "Post",
title: { $text: "genosdb" } // Matches "GenosDB", "genosdb", "GENOSDB"
}
})
Pattern Matching with $regex
Starts With
// Names starting with "Ana"
const { results } = await db.map({
query: {
name: { $regex: "^Ana" }
}
})
Ends With
// Emails ending with "@example.com"
const { results } = await db.map({
query: {
email: { $regex: "@example\.com$" }
}
})
Contains Pattern
// Descriptions containing "database" or "graph"
const { results } = await db.map({
query: {
description: { $regex: "(database|graph)" }
}
})
Wildcard Matching with $like
// Names like "J%" (starts with J)
const { results } = await db.map({
query: {
name: { $like: "J%" }
}
})
// Files ending with .pdf
const { results } = await db.map({
query: {
filename: { $like: "%.pdf" }
}
})
Examples
Search User Names
const searchUsers = async (searchTerm) => {
const { results } = await db.map({
query: {
type: "User",
name: { $regex: searchTerm }
},
field: "name",
order: "asc"
})
return results
}
const users = await searchUsers("ana")
console.log(`Found ${users.length} users matching "ana"`)
Multi-Field Text Search
// Search across multiple fields
const searchPosts = async (query) => {
const { results } = await db.map({
query: {
type: "Post",
$or: [
{ title: { $regex: query } },
{ content: { $regex: query } },
{ tags: { $in: [query] } }
]
}
})
return results
}
const posts = await searchPosts("javascript")
Tag Search
// Find posts with tags containing "java"
const { results } = await db.map({
query: {
type: "Post",
tags: { $regex: "java" }
}
})
Email Validation Query
// Find users with valid email format
const emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
const { results } = await db.map({
query: {
type: "User",
email: { $regex: emailRegex }
}
})
File Extension Search
// Find image files
const { results: images } = await db.map({
query: {
type: "File",
name: { $regex: "\\.(jpg|jpeg|png|gif|webp)$" }
}
})
// Find documents
const { results: docs } = await db.map({
query: {
type: "File",
name: { $regex: "\\.(pdf|doc|docx|txt)$" }
}
})
Autocomplete Search
const autocomplete = async (prefix) => {
const { results } = await db.map({
query: {
type: "User",
name: { $regex: `^${prefix}` }
},
$limit: 10
})
return results.map(user => user.value.name)
}
const suggestions = await autocomplete("Al")
// Returns: ["Alice", "Alan", "Alexandra", ...]
Search with Highlighting
const searchWithHighlight = async (searchTerm) => {
const { results } = await db.map({
query: {
type: "Post",
content: { $regex: searchTerm }
}
})
return results.map(post => ({
...post.value,
highlightedContent: post.value.content.replace(
new RegExp(searchTerm, "gi"),
match => `<mark>${match}</mark>`
)
}))
}
Real-Time Search
let currentSearch = null
const liveSearch = async (searchTerm) => {
// Unsubscribe from previous search
if (currentSearch) {
currentSearch.unsubscribe()
}
const { unsubscribe } = await db.map(
{
query: {
type: "Product",
$or: [
{ name: { $regex: searchTerm } },
{ description: { $regex: searchTerm } }
]
}
},
({ id, value, action }) => {
if (action === "initial" || action === "added") {
addToSearchResults(value)
}
}
)
currentSearch = { unsubscribe }
}
// User types in search box
searchInput.addEventListener("input", (e) => {
liveSearch(e.target.value)
})
Fuzzy Search Simulation
const fuzzySearch = async (term) => {
// Create regex with optional characters
const fuzzyPattern = term.split("").join(".*")
const { results } = await db.map({
query: {
type: "Product",
name: { $regex: fuzzyPattern }
}
})
return results
}
await fuzzySearch("gdb")
// Matches: "GenosDB", "GDB", "GraphDB", etc.
Full-Text Search with NLQ Module
When the Natural Language Query module is enabled (nlq: true):
const db = await gdb("my-db", { nlq: true })
// Natural language search
const { results } = await db.map({
prompt: 'Full text search "JavaScript"'
})
// Searches across common text fields:
// - name
// - role
// - level
// - country
// - title
// - body
// - tags
Inverted Index Module
For better performance on large datasets, enable the Inverted Index:
const db = await gdb("my-db", { ii: true })
// Searches are automatically optimized with the index
const { results } = await db.map({
query: {
content: { $text: "important keywords" }
}
})
Regular Expression Patterns
Common Patterns
// Phone numbers (US format)
const phonePattern = "^\\d{3}-\\d{3}-\\d{4}$"
// URLs
const urlPattern = "^https?://.*"
// Hashtags
const hashtagPattern = "#\\w+"
// Username (alphanumeric + underscore)
const usernamePattern = "^[a-zA-Z0-9_]{3,20}$"
// IP Address
const ipPattern = "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"
Using Patterns in Queries
// Find users with valid usernames
const { results } = await db.map({
query: {
type: "User",
username: { $regex: "^[a-zA-Z0-9_]{3,20}$" }
}
})
// Find posts with hashtags
const { results: tagged } = await db.map({
query: {
type: "Post",
content: { $regex: "#\\w+" }
}
})
Prefix Searches: For prefix-based searches, enable the Radix Index module (rx: true) for significant performance improvements:const db = await gdb("my-db", { rx: true })
// Optimized prefix search
const { results } = await db.map({
query: {
id: { $startsWith: "user:" }
}
})
Complex Regex: Very complex regular expressions can be slow on large datasets. Consider:
- Using simpler patterns when possible
- Enabling the Inverted Index module
- Combining with other filters to reduce the search space
Case Sensitivity
By default, text searches are case-insensitive. For case-sensitive searches:
// Case-insensitive (default)
const { results } = await db.map({
query: {
name: { $regex: "john" } // Matches "John", "JOHN", "john"
}
})
// Case-sensitive (use regex flags if your implementation supports it)
const { results } = await db.map({
query: {
name: { $regex: "(?-i)John" } // Only matches exact case
}
})