Skip to content

Omni Search

Gauravjeet Singh edited this page Aug 1, 2025 · 1 revision
Search Types

Search Types and Detection Logic

This document outlines the types of search inputs supported and how they are identified based on user queries.

Supported Search Types

These search types would be auto detected with this system.

  1. First Letter of Each Word (Gurmukhi)
  2. Full Word (Gurmukhi)
  3. Full Word Translation (English)
  4. Romanized First Letter (English)
  5. Ask a Question (English)
  6. Ang (Numeric)

Future Scope

These search types won't be auto detected yet, we can include them in future scope.

  • Romanized Gurmukhi (English)
  • Main Letters (Gurmukhi)

Search Type Detection Rules

The goal is to support accurate classification of user input for efficient search behavior.

Supported (Auto-Detected) Search Types

1. First Letter of Each Word (Gurmukhi)

Detection Rules:

  • Query has no spaces.
  • Query has no numbers
  • Query length is mostly between 4 and 12 characters (flexible but ideal).
  • It can have any of the 35 characters from ੳ-ੜ as per the following key map.
    image
  • i.e. it can only have one of the following characters aAeshkKgG|cCjJ\tTfFxqQdDnpPbBmXrlvS^Zz&LV

Example: ਸਚਨਕ


2. Full Word (Gurmukhi)

Detection Rules:

  • Query contains Gurmukhi words.
  • May contain spaces.
  • Words resemble valid Punjabi vocabulary (if lexicon is available).
  • Does not match Numeric or question patterns.

Example: ਸਚ ਪਾਉ


3. Full Word Translation (English)

Detection Rules:

  • Query contains only English characters (A-Z, a-z) and spaces.
  • Words are valid English (based on dictionary or NLP confidence).
  • Does not form a question (i.e., no interrogative format).
  • Does not contain numbers.

Example: true name


4. Romanized First letter (English)

  • Query has no spaces.
  • Query has no numbers
  • Query length is mostly between 4 and 12 characters (flexible but ideal).
  • It can have any of the 26 characters from a-z.
  • It doesn't matter if the query character is uppercase of lowercase.

Example: jtmvh


5. Ask a Question (English)

Detection Rules:

  • Query is in English.
  • Begins with or contains interrogative keywords: who, what, when, where, why, how, etc.
  • May or may not end with a ?.
  • May include pronouns, verbs indicating question formation.
  • Does not match any other format like numeric (Ang) or specific word searches.

Examples: What is meaning of life how to wake up early I need peace, how to get it?


6. Ang (numeric)

Detection Rules:

  • Query is only numeric (e.g., regex: ^\d+$).
  • No spaces, punctuation, or alphabetic characters.
  • Typically falls within a known valid Ang range (e.g., 1–1430).

Example: 212


Workflow for Search

This is the detection logic to classify user input into a supported search type and then perform a search using Meilisearch.

1. User Input:

  • User selects the language (Gurmukhi or English) and enters a search query.

2. Check if its Ang:

  • Check if the input is numeric (^\d+$)—if yes, classify as Ang.

3. Search Query Handling using Meilisearch:

  • Use full-text search on the following fields:
    • Gurmukhi (for full word Gurmukhi search)
    • Translations (for full word English search)
    • FirstLetterStr (for first letter Gurmukhi search)
    • MainLetters (for main letter Gurmukhi search)
    • FirstLetterEng (for first letter English search)

4. Search Execution in Meilisearch:

  • Meilisearch automatically ranks results by relevance based on the query.
  • Scoring is based on proximity, typo tolerance, and exactness.
  • You can also customize the ranking rules based on your requirements (e.g., boosting Gurmukhi matches).

5. Meilisearch Query Example:

const searchResults = await index.search(searchQuery, {
  attributesToRetrieve: ['ID', 'Gurmukhi', 'Translations', 'FirstLetterStr', 'MainLetters', 'FirstLetterEng'],
});

console.log(searchResults.hits);  // Display results ranked by relevance

Meilisearch Setup and Indexing

Step 1: Set Up Meilisearch

You need to install and run Meilisearch locally or use a hosted version. Here’s how to set up Meilisearch with Docker:

docker run -d -p 7700:7700 -e MEILI_MASTER_KEY='your_master_key' getmeili/meilisearch

Step 2: Define the Index

Create an index for storing verses in Meilisearch:

const { Client } = require('meilisearch');
const client = new Client({
  host: 'http://localhost:7700',  // URL for your Meilisearch instance
  apiKey: 'your_master_key',
});

// Create index for verses
const index = await client.createIndex('verses', {
  primaryKey: 'ID',
});

Step 3: Add Searchable Fields

Set up the fields for searching in Meilisearch:

await index.updateSettings({
  searchableAttributes: [
    'Gurmukhi', 
    'Translations', 
    'FirstLetterStr', 
    'MainLetters', 
    'FirstLetterEng',
  ],
  rankingRules: [
    'typo',           // Typo tolerance
    'words',          // Exact match
    'proximity',      // Proximity to search term
    'attribute',      // Attribute-based ranking
    'exactness'       // Exactness in matching the query
  ],
});

Step 4: Index Data from the Database

Fetch your verses from the database and add them to Meilisearch:

const documents = [
  {
    ID: 1,
    Gurmukhi: 'ਸਤਿ ਨਾਮੁ',
    Translations: 'True Name',
    FirstLetterStr: 'ਸ',
    MainLetters: 'ਸਤ..',
    FirstLetterEng: 'T..',
    // Additional columns...
  },
  // More verses...
];

await index.addDocuments(documents);
How to create the Meilisearch index from the BaniDB Verses?

This section outlines how to create a script to add data from BaniDB database to a Meilisearch index.

Step 1: Set Up Meilisearch Client

First, ensure we have a running Meilisearch instance.

docker run -d -p 7700:7700 -e MEILI_MASTER_KEY='master_key' getmeili/meilisearch

In your Node.js application, initialize the Meilisearch client:

const { Client } = require('meilisearch');

// Initialize the Meilisearch client
const client = new Client({
  host: 'http://localhost:7700',  // URL for your Meilisearch instance
  apiKey: 'your_master_key',     // Optional, if you set a master key
});

// Create or get an index for verses
const index = client.index('verses');  // Index name: 'verses'

Step 2: Fetch Data from Database

Next, fetch the verses (and related fields like Gurmukhi, Translations, etc.) from database.

const mysql = require('mysql2');

// Database connection
const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'your_database',
});

async function fetchVerses() {
  return new Promise((resolve, reject) => {
    pool.query('SELECT ID, Gurmukhi, Translations, FirstLetterStr, MainLetters, FirstLetterEng FROM Verse', (err, results) => {
      if (err) reject(err);
      resolve(results);  // Returns all verses
    });
  });
}

This function retrieves all the relevant data from the database.

Step 3: Prepare the Data for Meilisearch

Once the data is fetched from the database, format it for Meilisearch. Each verse will be added as a document with the required fields.

async function prepareDataForIndex() {
  const verses = await fetchVerses();

  const documents = verses.map(verse => ({
    ID: verse.ID,                    // Unique ID
    Gurmukhi: verse.Gurmukhi,         // Gurmukhi text
    Translations: verse.Translations, // English translation
    FirstLetterStr: verse.FirstLetterStr, // First letter (Gurmukhi)
    MainLetters: verse.MainLetters,   // Main letters (Gurmukhi)
    FirstLetterEng: verse.FirstLetterEng, // First letter (English)
  }));

  return documents;
}

Step 4: Add Data to Meilisearch

Now that the data is formatted correctly, add it to Meilisearch. Use the addDocuments method to index the documents.

async function addDocumentsToMeili() {
  const documents = await prepareDataForIndex();

  // Add the documents to Meilisearch
  try {
    const result = await index.addDocuments(documents);
    console.log('Documents added:', result);
  } catch (error) {
    console.error('Error adding documents to Meilisearch:', error);
  }
}

This function will send the documents to Meilisearch for indexing.

Step 5: Run the Script

To execute the script, simply call the addDocumentsToMeili function:

addDocumentsToMeili();

This will index all the verses from the database into Meilisearch.

Step 6: Periodic Updates (Optional)

To keep the Meilisearch index up to date, we can periodically update or delete documents in Meilisearch based on changes to the database:

  • Updating documents: If a verse is updated, we can use updateDocuments:
await index.updateDocuments([updatedVerse]);
  • Deleting documents: If a verse is deleted, we can use deleteDocuments:
await index.deleteDocuments([verseId]);

This process can be automated with a scheduled job (e.g., using cron jobs) to sync the database with Meilisearch periodically.


Step 5: Perform Search Queries

Once the data is indexed, we can start querying it using Meilisearch:

const searchResults = await index.search('True Name', {
  attributesToRetrieve: ['ID', 'Gurmukhi', 'Translations', 'FirstLetterStr', 'MainLetters', 'FirstLetterEng'],
});