Search layers
The search engine processes queries through three distinct layers, each providing progressively more sophisticated matching:1. Simple search layer
The first layer performs direct text matching using normalized Arabic.Simple search uses AND logic: all query tokens must be present in the verse for a match.
- Normalizes both query and verse text using
normalizeArabic() - Strips non-Arabic characters from the query
- Splits query into tokens by whitespace
- Returns verses where every token appears in the text
2. Linguistic search layer
The second layer uses morphological analysis to find lemma and root matches.Linguistic search requires morphology data and a word map to function. It can be disabled by setting
options.lemma = false and options.root = false.- Looks up the token in the word map to find its canonical lemma and root
- Searches morphology data for verses containing matching lemmas or roots
- Applies AND logic across tokens (all tokens must match)
- Finding different forms of the same word (inflections, conjugations)
- Matching words with the same linguistic root
- More comprehensive search results beyond exact text matches
3. Fuzzy search layer
The third layer uses Fuse.js as a fallback for tokens that don’t match exactly or linguistically.- threshold:
0.5(maximum allowed distance for a match) - distance:
100(how far to search for patterns) - ignoreLocation:
true(match anywhere in the text) - minMatchCharLength:
3(minimum characters required) - Searches both:
standardanduthmanitext fields
Combined search flow
The mainsearch() function orchestrates all three layers:
- Execute simple search and linguistic search in parallel
- Merge results and deduplicate by verse ID (gid)
- Compute scores for all matched verses
- Sort by score (highest first)
- Apply pagination
- Return results with metadata (counts, pagination info)
Deduplication ensures each verse appears only once in results, even if it matches through multiple layers.
Why this architecture?
This multi-layered approach provides: ✓ Precision: Exact matches score highest✓ Recall: Linguistic matching finds related forms
✓ Flexibility: Fuzzy search catches typos and variants
✓ Relevance: Scoring prioritizes better matches
✓ Performance: Each layer can be enabled/disabled based on needs