Search feels simple until it fails you. Type the wrong word and a keyword-based system will confidently return nothing, even when the exact file you need is sitting a few folders away, described in slightly different language. This gap between what we mean and what we type is the starting point for one of the most practically useful ideas in modern data science: semantic search. Rather than matching strings, semantic search compares meaning, and the shift from one to the other says a lot about how data science actually gets applied outside of research papers — quietly, inside ordinary tools people use every day.
This article walks through that shift using a concrete example: the semantic search layer I built into FileMapper, a personal file-indexing system, and the lessons that process taught me about applying machine learning to a real, resource-constrained problem.
Why Keywords Are Not Enough
A traditional search index matches tokens: if the word in the query is not the word in the document, there is no match, regardless of how closely related the two words are in meaning. This is fine for exact lookups, but it breaks down for the kind of search people actually want to do — finding "the file about neural networks" when the document itself only mentions "deep learning," or finding a report on "customer churn" using the query "user retention." Humans reason about concepts, not strings, and any system built only on string matching will systematically fail exactly the queries where a person is least sure of the file's precise wording — which, in practice, is most of them.
From Words to Vectors
The core idea behind semantic search is to represent text not as a string but as a vector of numbers — an embedding — produced by a language model trained so that texts with similar meaning end up close together in that numerical space, and unrelated texts end up far apart. Once every document and every query is converted into this shared numerical space, "search" becomes a geometry problem: find the documents whose vectors sit closest to the query's vector. This reframing is powerful precisely because it is general — the same underlying technique applies whether you are matching resumes to job postings, support tickets to knowledge-base articles, or, in my case, personal files to a plain-language search query.
Applying This in Practice: FileMapper
I implemented this idea as one layer of FileMapper, a local-first file indexing system I built in Python with SQLite as its backend. Alongside the traditional keyword index, FileMapper generates an embedding for each file's extracted content using a compact, locally-run sentence-transformer model, and stores that embedding as a vector alongside the file's other metadata. When a user runs a semantic query, the system embeds the query the same way and ranks indexed files by how close their embeddings are to it — surfacing files that are conceptually relevant even when no keyword overlaps.
The same mechanism powers a related-files feature: given one document, the system can suggest others that are semantically similar, which is especially useful for connecting personal notes that were written on different days, in different words, but about the same underlying idea.
python Main.py search "machine learning" --semantic
python Main.py related "/path/to/note.md"
Engineering Constraints Shape the Data Science
Building this taught me that applying machine learning in a real product is as much an engineering problem as a modeling one. Three constraints in particular shaped my decisions:
- Local-first. No file content could be sent to an external API, which meant the embedding model had to run entirely on-device rather than relying on a hosted service.
- Stay fast. Everyday commands like listing or filtering files had to stay fast, so the embedding model is loaded lazily — only when a semantic query actually needs it — rather than on every program start.
- Recompute only on change. Embeddings only needed to be recomputed when a file's content actually changed, not on every scan, since recomputing them unnecessarily would waste time without improving results. None of these constraints are exotic in data science practice; they are the ordinary cost of moving a technique from a notebook into something people rely on daily.
What This Taught Me About Data Science
The most valuable lesson from this project was not the embedding model itself — that part is largely off-the-shelf — but everything around it: deciding what to store, how to keep an index synchronized with a constantly changing file system, and how to make a probabilistic technique like similarity search feel dependable in a tool people use for something as unforgiving as "find my file."
It reinforced a view I now hold about data science generally: the model is often the easy part, and the real work is in the data pipeline, the constraints, and the judgment calls about where an approximate, learned answer is good enough and where it isn't. That is the kind of judgment I want to keep developing.
Conclusion
Semantic search is a small example of a much larger pattern in data science: taking a technique that sounds academic — vector embeddings, similarity in high-dimensional space — and using it to solve an ordinary, everyday problem. Building that pattern myself, end to end, from raw files to a working semantic index, gave me a much more concrete understanding of both the promise and the practical limits of applied machine learning than any tutorial could have.
Top comments (0)