Document Search Engine
Part of the AI Engineer Roadmap
In short
Sometimes people want the right document, not a chatbot's answer. A search engine over PDFs, notes or policies, ranked by meaning and filterable by type, is a practical project that teaches retrieval deeply.
A semantic search tool over a document collection — a simpler sibling to the Q&A chatbot that focuses purely on retrieval quality without generation.

Think of it like this
The library card catalogue
Old libraries had wooden cabinets of index cards. Each card pointed to a book, with the subject, author and shelf. You'd flip to the right drawer and find the card in seconds. Your search engine is a modern catalogue that also understands what you meant.
Watch it happen
One search request
q=exam rules&dept=cse
1/6The user searches 'exam rules' and filters to the CSE department.
The big ideas
What you need to know
Results are documents
Search chunks, but show documents. Group hits by file and show the best snippet from each.
Filters matter
Department, year and file type filters make search useful. Store them as metadata at index time.
Hybrid by default
Users type codes, names and natural phrases. Combining keyword and vector search handles all three.
Fast feels smart
Aim for results in well under a second. Cache embeddings for popular queries.
See it in code
Walk through the code
1from collections import defaultdict2 3def search(collection, query: str, dept: str | None = None, k: int = 20):4 where = {"dept": dept} if dept else None5 hits = collection.query(query_texts=[query], n_results=k, where=where)6 7 best = defaultdict(lambda: None)8 for doc, meta, dist in zip(hits["documents"][0], hits["metadatas"][0], hits["distances"][0]):9 f = meta["file"]10 if best[f] is None or dist < best[f]["dist"]:11 best[f] = {"file": f, "page": meta["page"], "snippet": doc[:200], "dist": dist}12 13 return sorted(best.values(), key=lambda r: r["dist"])[:5]1/3Apply the department filter inside the vector query.
Search chunks in Chroma with an optional filter, then keep the closest chunk per file as its snippet.
Save yourself the pain
Common mistakes
Oops
Showing 20 chunks where 15 come from the same PDF.
Do this instead
Group by document so users see a variety of relevant files, each with one strong snippet.
Oops
Forgetting to store page numbers at index time.
Do this instead
Add file and page metadata when chunking. You can't recover it later without re-indexing.
Your mission
First milestone: grouped results
Quick check
Why group chunk results by document in a search engine?
Go deeper
- 1Index a real document collection and build a search UI with relevance-ranked results.
- 2Add filters (date, category, source) alongside semantic search.
- 3Evaluate ranking quality with a small set of known relevant results per query.
More projects at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.