npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@fondation-io/fast-db-batch-search-client

v3.1.0

Published

TypeScript client for Fast-DB batch search API with support for fuzzy search

Readme

Fast-DB Batch Search Client

npm version Build Status npm downloads License: MIT Bundle Size

A TypeScript client library for interacting with Fast-DB's batch search API, providing efficient batch queries with support for fuzzy search operations.

Features

  • 🚀 Batch Operations: Execute multiple search queries in a single request
  • 🔍 Fuzzy Search: Built-in support for fuzzy string matching with Levenshtein distance
  • 🔗 Join Support: Query across multiple related tables with inner/left/right/full joins
  • 📊 Progress Tracking: Real-time progress updates for batch operations
  • 🎯 Type Safety: Full TypeScript support with comprehensive type definitions
  • High Performance: Optimized for handling large datasets
  • 🔄 Automatic Retries: Built-in retry logic for failed requests

Installation

NPM/Yarn Installation

# Using npm
npm install @fondation-io/fast-db-batch-search-client

# Using yarn
yarn add @fondation-io/fast-db-batch-search-client

# Using pnpm
pnpm add @fondation-io/fast-db-batch-search-client

Git Installation

Install directly from GitHub:

npm install git+https://github.com/fondation-io/fast-db-batch-search-client.git

As a Git Submodule

For projects that need to modify or closely track the client:

# Add as submodule
git submodule add https://github.com/fondation-io/fast-db-batch-search-client.git libs/fast-db-client

# Install dependencies
cd libs/fast-db-client
npm install
npm run build

Quick Start

import { BatchSearchClient } from '@fondation-io/fast-db-batch-search-client';
// Note: FastDBBatchSearchClient is also available as an alias for backward compatibility

// Initialize the client
const client = new BatchSearchClient({
  baseUrl: 'http://localhost:8080',
  timeout: 30000,
  includeMetrics: true,
});

// Search for multiple Harry Potter books by J.K. Rowling
const results = await client.batchSearch(
  'books', // table/collection
  'auteurs', // node field (author field name)
  'J.K. Rowling', // node query (author to search for)
  'titre', // target field (title field name)
  [
    // target queries (list of titles to search)
    'Harry Potter école sorciers',
    'Harry Potter chambre secrets',
    'Harry Potter prisonnier Azkaban',
  ],
  ['titre', 'auteurs'], // fields to return
  true, // use fuzzy search
  5 // max results per target
);

console.log(`Found ${results.totalResults} books`);
console.log(results.grouped); // Results grouped by search query

Conceptual Model: Node-Target Relationships

The batch search API uses a generic node-target model that can represent various relationships:

  • Node: The common element that groups related items (e.g., author, category, parent)
  • Target: The specific items being searched within that group (e.g., titles, products, children)

This model supports many use cases:

  • Books by an author: node=author, targets=book titles
  • Products in a category: node=category, targets=product names
  • Children of a parent entity: node=parent_id, targets=child names
  • Tracks by an artist: node=artist, targets=track titles
  • Items with a common tag: node=tag, targets=item names

Advanced Use Cases with Joins

When data is spread across multiple tables, use batchSearchWithJoins:

  • Music Database: Search albums by artist where artists and albums are in separate tables
  • E-commerce: Find products by manufacturer with separate manufacturer and product tables
  • Library System: Search books by author with separate author and book tables
  • Movie Database: Find movies by director/actor with separate person and movie tables

Configuration

Client Options

interface BatchSearchOptions {
  baseUrl?: string; // Fast-DB server URL (default: 'http://localhost:8080')
  timeout?: number; // Request timeout in milliseconds (default: 30000)
  includeMetrics?: boolean; // Include performance metrics (default: true)
}

Environment Variables

You can also configure the client using environment variables:

FAST_DB_URL=http://localhost:8080
FAST_DB_TIMEOUT=30000

API Reference

Main Client

batchSearch(table, nodeField, nodeQuery, targetField, targetQueries, projection?, fuzzy?, resultsPerQuery?)

Search for multiple targets related to a single node.

Parameters:

  • table (string): The table/collection to search in (e.g., 'books')
  • nodeField (string): The field name containing node information (e.g., author, category, parent)
  • nodeQuery (string): The node value to search for
  • targetField (string): The field name containing target information (e.g., title, name, child)
  • targetQueries (string[]): Array of target values to search for
  • projection (string[]): Fields to return (default: ['*'])
  • fuzzy (boolean): Use fuzzy search (default: true)
  • resultsPerQuery (number): Maximum results per target (default: 10)
// Example: Search for books by author
const bookResults = await client.batchSearch(
  'books',
  'auteurs', // node field
  'Victor Hugo', // node query
  'titre', // target field
  ['Les Misérables', 'Notre-Dame de Paris', 'Les Contemplations'], // target queries
  ['titre', 'auteurs', 'annee'],
  true,
  3
);

// Example: Search for products by category
const productResults = await client.batchSearch(
  'products',
  'category', // node field
  'Electronics', // node query
  'product_name', // target field
  ['iPhone', 'MacBook', 'AirPods'], // target queries
  ['product_name', 'price', 'brand'],
  true,
  5
);

batchSearchWithJoins(params: JoinSearchParams)

Execute batch search queries across multiple tables with join support.

Parameters:

interface JoinSearchParams {
  tables: string[]; // Tables to join
  joins: JoinCondition[]; // Join conditions
  nodeField: string; // Node field (can include table prefix)
  nodeQuery: string; // Node value to search
  targetField: string; // Target field (can include table prefix)
  targetQueries: string[]; // Target values to search
  projection?: string[] | Record<string, string>; // Fields to return
  fuzzy?: boolean; // Use fuzzy search (default: true)
  resultsPerQuery?: number; // Max results per target (default: 10)
  orderBy?: Record<string, number>; // Sort order
  limit?: number; // Total result limit
}

interface JoinCondition {
  $type: 'inner' | 'left' | 'right' | 'full';
  $left: string;
  $right: string;
  $on: [string, string];
}

Example:

// Search for Mozart albums with joins
const mozartAlbums = await client.batchSearchWithJoins({
  tables: ['id_artists', 'album_artist', 'albums'],
  joins: [
    {
      $type: 'inner',
      $left: 'id_artists',
      $right: 'album_artist',
      $on: ['id_artists.id', 'album_artist.artist_id'],
    },
    {
      $type: 'inner',
      $left: 'album_artist',
      $right: 'albums',
      $on: ['album_artist.cb', 'albums.cb'],
    },
  ],
  nodeField: 'id_artists.artiste',
  nodeQuery: 'Mozart',
  targetField: 'albums.album',
  targetQueries: ['Symphony 40', 'Symphony 41', 'Requiem'],
  projection: {
    artist_name: 'artiste',
    album_title: 'album',
    release_year: 'street_date',
  },
  fuzzy: true,
  resultsPerQuery: 5,
  orderBy: { release_year: -1 },
});

searchAlbumsByArtist(artist, albumTitles, maxPerAlbum?)

Convenience method for searching albums by artist using joins.

const albums = await client.searchAlbumsByArtist(
  'Mozart',
  ['Symphony 40', 'Symphony 41', 'Requiem'],
  5
);

searchBookSeries(author, seriesTitles, maxPerTitle?) (Deprecated)

Deprecated: Use searchRelatedItems() instead.

Convenience method for searching book series by author.

searchRelatedItems(table, nodeField, nodeValue, targetField, targetValues, projection?, maxPerTarget?)

Generic method for searching related items by a common node.

// Deprecated method (for backward compatibility)
const results = await client.searchBookSeries(
  'J.R.R. Tolkien',
  ['The Hobbit', 'The Lord of the Rings', 'The Silmarillion'],
  5
);

// Recommended: Use the generic method
const results = await client.searchRelatedItems(
  'books',
  'auteurs',
  'J.R.R. Tolkien',
  'titre',
  ['The Hobbit', 'The Lord of the Rings', 'The Silmarillion'],
  ['titre', 'auteurs', 'annee'],
  5
);

Response Structure

interface BatchSearchResponse {
  results: SearchResult[]; // Flat array of all results
  grouped: GroupedResults; // Results grouped by title query
  metrics?: Record<string, unknown>; // Performance metrics
  totalResults: number; // Total number of results found
}

interface SearchResult {
  search_group_hash: string; // Hash identifying which title query this result belongs to
  [key: string]: any; // Dynamic fields based on projection
}

interface GroupedResults {
  [hash: string]: SearchResult[]; // Results grouped by search_group_hash
}

Advanced Usage

Error Handling

try {
  const results = await client.batchSearch(
    'books',
    'auteurs',
    'Unknown Author',
    'titre',
    ['Some Title'],
    ['titre'],
    true,
    5
  );
} catch (error) {
  console.error('Search failed:', error.message);
  // Handle specific error cases
  if (error.message.includes('Network error')) {
    console.error('Server is unreachable');
  } else if (error.message.includes('API Error')) {
    console.error('Server returned an error');
  }
}

Examples

Search for Multiple Books by One Author

// Search for Harry Potter books by J.K. Rowling
const harryPotterResults = await client.batchSearch(
  'books',
  'auteurs',
  'J.K. Rowling',
  'titre',
  [
    "Harry Potter and the Philosopher's Stone",
    'Harry Potter and the Chamber of Secrets',
    'Harry Potter and the Prisoner of Azkaban',
    'Harry Potter and the Goblet of Fire',
    'Harry Potter and the Order of the Phoenix',
    'Harry Potter and the Half-Blood Prince',
    'Harry Potter and the Deathly Hallows',
  ],
  ['titre', 'auteurs', 'annee', 'isbn'],
  true, // fuzzy search
  3 // max 3 results per title
);

// Process grouped results
for (const [hash, books] of Object.entries(harryPotterResults.grouped)) {
  console.log(`\nGroup ${hash}:`);
  books.forEach((book) => {
    console.log(`- ${book.titre} (${book.annee})`);
  });
}

Using the Convenience Method

// Search for Tolkien's major works
const tolkienResults = await client.searchBookSeries(
  'J.R.R. Tolkien',
  ['The Hobbit', 'The Fellowship of the Ring', 'The Two Towers', 'The Return of the King'],
  5 // max 5 results per title
);

console.log(`Found ${tolkienResults.totalResults} books by Tolkien`);

Performance Tips

  1. Batch Size: Optimal batch size is typically 100-500 queries
  2. Field Selection: Specify only required fields to reduce response size
  3. Connection Pooling: The client reuses connections automatically
  4. Timeout Configuration: Adjust timeout based on your dataset size

Development

Building from Source

# Clone the repository
git clone https://github.com/fondation-io/fast-db-batch-search-client.git
cd fast-db-batch-search-client

# Install dependencies
npm install

# Build the project
npm run build

# Run tests
npm test

# Run in watch mode
npm run watch

Running Examples

# Basic example
npm run example

# Advanced example
npx tsx examples/advanced-search.ts

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Support

Acknowledgments

This client is part of the Fast-DB ecosystem, a high-performance in-memory database optimized for search operations.