Short answer. An app’s search is not a field looking for the exact word in the product name: it is an index built from several fields per product, French name, Arabic name, synonyms and Latin-letter variants, reference, brand, packaging; a normalisation that unifies Arabic forms, strips accents and separates units from numbers; hand-written synonyms with the manager, because no engine knows that “zit” is oil or that “smid” is semolina; a tuned typo tolerance, one typo from five letters, two from nine; a ranking where text rules come first, words found, typos, proximity, then business rules, availability, price for this customer, products already ordered, never as silent filters; a set of two hundred real queries replayed at every change; and a zero-result log that is the source of the next synonyms. Six weeks, the first without touching the engine.
This guide is for the founder settled in France whose portal or marketplace shows “no results” to customers typing in darija, the wholesaler in Algeria whose retailers call the sales rep because they cannot find the product in the app, and anyone comparing quotes where “search” is one word. It does not cover AI search in documents, described in the guide on AI in the app, but connects to it at the end; it describes what gets built between the customer’s keystroke and the list of results.
What the figures say
Typo tolerance is tunable, not magic. The documentation of Meilisearch, an open search engine we often use, says typo tolerance is enabled by default, that one typo is accepted from five characters and two from nine, and that a typo on the first letter counts double; its default ranking rules apply in the order words, typo, proximity, attribute, sort, exactness, and custom rules, a sorted numeric field, go at the end. For Arabic, the same documentation announces segmentation of the article “ال” and normalisation by decomposition, digit conversion and removal of non-spacing marks; it says nothing about alef forms, which we unify ourselves before indexing. What this imposes: “huille” finds “huile”, “الزيت” finds “زيت”, but “zit” finds nothing without a synonym written by someone.
The database already knows a lot. PostgreSQL, which most of our apps use, provides full-text search with chained dictionaries, including a filtering dictionary that removes accents and Snowball stemmers that, according to the documentation, “recognize everything” and therefore go at the end of the chain; the page does not list languages, and we do not rely on a stemmer for dialectal Arabic. Its trigram extension measures the similarity of two strings with a default threshold of 0.3, ignores non-alphanumeric characters, and its indexes speed up `LIKE` and `ILIKE` searches; that is enough for a back office of a few thousand references. What this imposes: the first question is not “which engine” but “what size, what use, and who will run it”.
What exists nowhere: a dictionary of Latin-letter darija. “zit”, “zite”, “zeit”, “smid”, “sokar”, “7lib” for milk with the digit standing for a letter: every company has its own, and it is built from what its customers really type. That is why the figure to read is not the number of searches but the share of zero results, query by query, with the customer and the time, and why the project’s first week is spent with the sales reps and the manager’s phone rather than with an engine. What we did not find: a public measure of Latin-darija use in searches in Algeria; what we see in pilots is that it is the first cause of zero results on a food catalogue, and we say so as an observation, not a statistic.
A “zit 5l” search, from keystroke to result
A search is not described by its engine but by what happens to what the customer types, letter by letter, up to the result and the log.
The keystroke: the retailer writes “zit 5l”, in darija, in Latin letters, no accent, no space before the unit, and the search runs on every letter. Normalisation lowercases, splits “5l” into “5 l”, and consults the synonyms: “zit” also becomes “huile”; a typo would have been tolerated from five letters. Matching happens on the product document, which is not a database row but a set of indexed fields: the French name finds “huile” and “5 l”, the Arabic name would have found “زيت” without the article, and the synonyms field, hand-written in week one, finds “zit” itself.
The result shows the name in both languages, availability and the price for this customer, because two retailers do not see the same catalogue at the same price, as the B2B portal guide describes. The log writes the query, the number of results, the response time, then the click; and every week, the share of zero results and the list of terms that returned nothing, which is the source of the next synonyms. A search that does not log never improves: it fails the same way for the same word for months.
Building the index, in six steps
Behind the result, six steps, and the third is the one no engine does for you.
The fields: for each product, the French name, the Arabic name, synonyms and Latin-letter variants, reference, barcode, brand, category, unit and packaging; one document per product, with a weight per field, the reference weighing more than the description. Normalisation: lowercase, accents removed, alef forms and taa marbuta unified, Arabic and Latin digits aligned, units separated from numbers; applied to the index and to the query the same way. Synonyms: hand-written with the manager and the sales reps, two hundred lines in week one, Latin darija to the French name, abbreviations, old references, brands pronounced differently; stored in your database, versioned, and checked on the query set.
The index: a dedicated engine for a catalogue consulted from a phone, or the database’s full-text and trigram index for a back office; one document per product, refreshed on every price or stock change, because a result showing yesterday’s price loses an order. Business rules: availability, price for this customer, products already ordered, products on the route, new items, placed after the text rules as ranking rules, never as filters that make a product disappear. The query set: two hundred real queries with the expected product, replayed at every change of synonyms, normalisation or rules, with a score; release refused if the score drops, on the same principle as the tests described in the delivery guide.
«No engine knows that “zit” is oil; it is a synonym someone writes, and the zero-result log says which ones are missing.»
Why result 1 comes first
Ranking is what the customer sees without knowing it: the same query, the same products, and an order that decides whether they order or call the sales rep.
Text rules first: the product containing all the query words goes before the one containing only one; no typo before with typo; words close together before words far apart. That is the default order of common engines, and it is not up for debate. Business rules next: in stock before out of stock, but out of stock stays visible, because a product that disappears makes the retailer believe it no longer exists; the price for this customer, because a product at their negotiated rate deserves to rise; the products they already ordered, because they often look for the same thing. These rules are written with the manager in week four, and they change by trade: a pharmacy ranks by expiry date, a distributor by route.
What must never rank: margin, unless the manager asks for it in writing and owns it; and no rule may push ahead a product that does not contain the query words. The parts in the figure are illustrative; what is not is that every rule has a written weight, that the query set measures the effect of every weight change, and that the retailer who types an exact reference or a barcode gets that product alone, first, before any text search.
Six real queries, and what the engine must do
Six queries we pick up from the search logs of the apps we build, and what the engine must do for each.
Latin-letter darija is the first cause of zero results on a food catalogue: “zit”, “smid”, “sokar”, with their variants; only hand-written synonyms find it, and the list lives with the log. Arabic with or without article, with or without dots and vowels: article stripped, forms unified, marks ignored, and the same result in both scripts; that is step two’s normalisation. The typo: one tolerated from five letters, two from nine, the first letter counting double, and the exact result always first; short words, “lait”, “thé”, have no tolerance and are covered by synonyms.
The reference or barcode: exact match before any text search, a single result, first; that is the query of the pre-seller who scans, described in the field app guide. The generic word: “huile” gives dozens of results, and ranking does the work, availability, already ordered, price, with brand and packaging facets to narrow down. Nothing matches: zero result logged with the customer and the time, nearby products suggested rather than an empty page, and the list reviewed every week; it is the row that improves all the others.
Four ways to build search
Four approaches, and the choice depends on catalogue size, use and who will run the service, not on fashion.
The database index, full text and trigrams, is enough up to a few tens of thousands of products for a back office or an internal search: accents removed by a filtering dictionary, typos by trigram similarity with an adjustable threshold, synonyms by table; nothing more to host or monitor, but no Arabic article segmentation and no search-as-you-type on a large catalogue. The self-hosted open dedicated engine is our usual choice for a customer catalogue, a B2B portal or a marketplace: typos tolerated by default, ordered ranking rules, Arabic segmented, native synonyms, search-as-you-type in a few tens of milliseconds on an index of that size, to be measured; it is one more service to host, back up and update, per the hosting guide.
The same engine as a managed service avoids running it yourself, at the price of a subscription in foreign currency paid from Algeria, described in the guide on paying for cloud, and catalogue data hosted at the vendor, to decide by contract. Semantic search by vectors understands “oil for frying” without a synonym and answers natural-language questions on documents; it does not guarantee the exact reference and combines with text ranking rather than replacing it; it is the function described in the guide on AI in the app, and it has its cost per document and per query. None of the four knows “zit”: the synonyms remain to be written, whatever the engine.
«An out-of-stock product drops down the list; it does not disappear, or the retailer believes it no longer exists.»
Seen elsewhere: Meilisearch, PostgreSQL, and what transposes
Two sources say the essentials. The Meilisearch documentation says typo tolerance is on by default with thresholds of five and nine letters, that ranking rules apply in a written order, and that Arabic is segmented and normalised; what transposes is that typos and standard Arabic are settled by configuration, and that everything else, Latin darija, units, business rules, is to be built. The PostgreSQL documentation says a filtering dictionary removes accents, that stemmers go at the end of the chain, and that trigrams measure a similarity with a 0.3 threshold; what transposes is that a back office does not need one more engine.
What these sources do not say: which words your customers type, what share of zero results you have today, and which business rules your manager wants to see rank; the project’s first week answers that, with the existing app’s log when there is one, and with the sales reps when there is not.
The rules of a search that finds
Six rules, written in the first week and reread at every synonym addition. Real queries before the engine: what customers type, collected from the sales reps and the log, decides the fields, the synonyms and the query set. The same normalisation at index and query, Arabic and Latin. The synonyms are yours, in your database, versioned, not in a vendor’s console. Business rules rank, they do not filter: an out-of-stock product drops, it does not disappear. The exact reference always wins. Zero results is the figure read every week, with the list of terms, and every term added to the synonyms is replayed on the query set.
A seventh rule concerns the quote: “search” is not a requirement, it is a sentence; the requirement reads “index on French name, Arabic name, synonyms, reference, barcode; Arabic and Latin normalisation; two hundred synonyms written with the manager; one typo tolerated from five letters; text ranking then availability, customer price, already ordered; set of two hundred queries with score measured at acceptance; zero-result log; search-as-you-type under fifty milliseconds measured”, and it is checked as the specification guide recommends. A quote that prices “a search field” has priced a `LIKE`.
Six apps, and what their search must find
Six apps we often build, and for each what the search must find first, decided in the first week.
- The B2B ordering portal, described in the dedicated guide. Latin darija and Arabic to the catalogue, price for this customer in the ranking, exact barcode; zero results read every week with the sales reps.
- The marketplace, described in the dedicated guide. Thousands of sellers, product names written a thousand ways; strong normalisation, synonyms per category, facets, and availability per seller in the ranking.
- The pre-sellers’ field app, described in the dedicated guide. Barcode scan first, then offline search on the local index described in the offline guide; the route’s products first.
- The pharmaceutical wholesaler, described in the cold-chain guide. Generic name and brand name as synonyms of each other, dosage and form as fields, expiry date in the ranking.
- The owner’s space for a flat, described in the dedicated guide. Search in receipts, inventories and works by date, tenant and amount; the database index is enough.
- The owner’s dashboard, described in the dedicated guide. Search for a customer, an order or an invoice by number, name or phone, with typos; database trigrams, no extra engine.
The 2027 calendar
The calendar is that of a complete search in six weeks, the first without touching the engine and one of acceptance with real retailers.
Week 0 to 1 collects real queries and writes the synonyms: the words customers really type, gathered from the sales reps, the manager’s phone and the existing app’s log if there is one; two hundred synonyms written and signed. Week 1 to 2 sets the fields and normalisation, Arabic and Latin, the units, and the set of two hundred queries with the expected product. Week 2 to 3 installs the engine or the database index, loads the documents, wires reindexing on every change, and measures search-as-you-type. Week 3 to 4 writes the business rules and facets with the manager, every weight measured on the query set.
Week 4 to 5 is acceptance: the score on the query set, zero results counted, and ten real retailers searching in front of us, because the team always types the right name. Week 5 to 6 is the pilot: log read every week, synonyms added, score replayed, and the share of zero results falling week after week is the figure that says the search is alive. Every batch is demoed and accepted as the delivery guide describes.
What makes search fail
The searches we take over almost always failed for one of these reasons.
- The `LIKE` field. Exact, slow on a large catalogue, and silent: nobody knows what customers typed without result.
- No synonyms. The engine tolerates typos, but “zit” is not a typo; it is a word nobody wrote.
- Arabic not normalised. “الزيت” and “زيت” are two different words; the customer types one and the product carries the other.
- Out of stock filtered. The product disappears; the retailer believes it no longer exists and orders elsewhere.
- Acceptance on exact names. The team searches “Huile de tournesol 5 L” and everything works; the retailer searches “zit” and nothing works.
- The lagging index. The price changed this morning; search shows yesterday’s.
- No log. Search fails the same way for the same word for months, and nobody knows.
Frequently asked questions
The questions we receive from founders settled in France, managers in Algeria and teams comparing quotes.
- Why can’t my customers find the product when it exists?
- Because they do not type the name the product carries: “zit” for oil, “الزيت” with the article, “huille” with a typo, or the unit stuck to the number. A field looking for the exact word finds nothing; an index with normalisation, hand-written synonyms and typo tolerance finds the first three, and the zero-result log says which are still missing.
- Does the search understand darija in Latin letters?
- No engine knows it: “zit”, “smid”, “sokar” and their variants are synonyms hand-written with the manager and the sales reps in week one, two hundred lines for a food catalogue, then completed every week from the queries without result. The synonyms are stored in your database, not at a vendor’s.
- And Arabic with or without article, with or without vowels?
- Normalisation handles it: article “ال” stripped, alef forms and taa marbuta unified, vowel marks ignored, Arabic and Latin digits aligned, applied the same way to the index and the query. A dedicated engine does part of this work by default; the rest we add before indexing, and the query set checks it.
- How many typos does the search tolerate?
- One typo from five letters, two from nine, a typo on the first letter counting double: those are the default settings of a common engine, and they can be changed. Short words, “lait”, “thé”, have no tolerance and are covered by synonyms; and the exact result always stays first.
- Do we need a search engine on top of the database?
- Not always. For a back office or an internal search up to a few tens of thousands of references, the database’s full-text and trigram index is enough, with no extra service. For a catalogue consulted from a phone, a B2B portal or a marketplace, a self-hosted open dedicated engine brings search-as-you-type, typos, segmented Arabic and ranking rules; it is one more service to host, and it is yours.
- How long to build the search?
- Six weeks for a complete search: one for real queries and synonyms without touching the engine, one for fields, normalisation and the query set, one for the index, one for business rules, one of acceptance with ten real retailers, one of pilot with the log. Every batch is demoed and accepted on the query set.