<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Module 3: Sparse vs Dense vs Hybrid Search on Qdrant - Vector Search Engine</title><link>https://qdrant.tech/course/beginners/module-3/</link><description>Recent content in Module 3: Sparse vs Dense vs Hybrid Search on Qdrant - Vector Search Engine</description><generator>Hugo</generator><language>en-us</language><managingEditor>info@qdrant.tech (Andrey Vasnetsov)</managingEditor><webMaster>info@qdrant.tech (Andrey Vasnetsov)</webMaster><atom:link href="https://qdrant.tech/course/beginners/module-3/index.xml" rel="self" type="application/rss+xml"/><item><title>Module Overview</title><link>https://qdrant.tech/course/beginners/module-3/module-overview/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/module-overview/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="sparse-vs-dense-vs-hybrid-search"&gt;Sparse vs Dense vs Hybrid Search&lt;/h1&gt;
&lt;div class="video"&gt;
&lt;iframe src="https://www.youtube.com/embed/WntUDHOuOqQ?rel=0" 
 frameborder="0" 
 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
 referrerpolicy="strict-origin-when-cross-origin" 
 allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Understand dense versus sparse retrieval, their strengths, and how a hybrid approach can combine them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Follow-along code&lt;/strong&gt;: &lt;a href="https://github.com/qdrant/examples/blob/master/course/beginners/Module3.ipynb" target="_blank" rel="noopener nofollow"&gt;Module 3 notebook&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="overview"&gt;Overview&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Module 2 showed you where your data lives and how Qdrant retrieves it.
In this module, you&amp;rsquo;ll learn what that retrieval misses and how to cover the gap.
You&amp;rsquo;ll explore dense and sparse vectors, BM25, and the inverted index, then see
why a product code defeats either one alone. You&amp;rsquo;ll also learn how fusion merges
two ranked lists, and where a filter belongs so both retrievers respect it.
By the end, you&amp;rsquo;ll have built a hybrid collection, run a fused query,
and filtered it correctly.&lt;/p&gt;</description></item><item><title>Where We Left Off</title><link>https://qdrant.tech/course/beginners/module-3/where-we-left-off/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/where-we-left-off/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="where-we-left-off"&gt;Where We Left Off&lt;/h1&gt;
&lt;p&gt;In Module 2, you built a complete ingestion and retrieval pipeline: raw text, vector, store, top-K query. Dense retrieval handles meaning well. It gets shaky on the part of a query that has to be exact.&lt;/p&gt;
&lt;p&gt;Here is a shoe catalog with two products one digit apart. Searching it dense-only for &lt;code&gt;Nike Pegasus 40&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Result&lt;/th&gt;
 &lt;th&gt;Dense score&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Nike Pegasus 40 running shoes&lt;/td&gt;
 &lt;td&gt;0.8713&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Nike Pegasus 41 running shoes&lt;/td&gt;
 &lt;td&gt;0.8626&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Nike Pegasus 40 womens running shoes&lt;/td&gt;
 &lt;td&gt;0.7830&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Nike Pegasus Trail 4 trail running shoes&lt;/td&gt;
 &lt;td&gt;0.7425&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="the-problem"&gt;The Problem&lt;/h3&gt;
&lt;p&gt;Dense ranks the right shoe first, so nothing here looks broken. Look at the margin: &lt;strong&gt;0.0087&lt;/strong&gt;, about one percent of the top score. To the model, &amp;ldquo;Pegasus 40&amp;rdquo; and &amp;ldquo;Pegasus 41&amp;rdquo; are near-identical statements about running shoes, because that is what they are. The digit a shopper cares about is one token out of five, averaged into a vector describing the whole phrase.&lt;/p&gt;</description></item><item><title>The Two Families of Search</title><link>https://qdrant.tech/course/beginners/module-3/the-two-families-of-search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/the-two-families-of-search/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="the-two-families-of-search"&gt;The Two Families of Search&lt;/h1&gt;
&lt;p&gt;Every retrieval system is built from one or both of these.&lt;/p&gt;
&lt;h3 id="dense-search"&gt;Dense Search&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://qdrant.tech/courses/beginners/module-3/dense-search.png" alt="Two similar phrases encoded as dense vectors, landing near each other."&gt;&lt;/p&gt;
&lt;p&gt;A dense vector has a small, fixed number of dimensions, 384 for the model used here, and every one of them holds a value. Two texts with similar meaning land close together whether or not they share any words:&lt;/p&gt;</description></item><item><title>Hybrid Search: Dense and Sparse</title><link>https://qdrant.tech/course/beginners/module-3/hybrid-search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/hybrid-search/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="hybrid-search-dense-and-sparse"&gt;Hybrid Search: Dense and Sparse&lt;/h1&gt;
&lt;p&gt;Hybrid search runs both retrievers in the same request and combines their ranked lists into one result set.&lt;/p&gt;
&lt;p&gt;Run the same &lt;code&gt;Nike Pegasus 40&lt;/code&gt; query through sparse alone and the picture inverts. The top three:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Result&lt;/th&gt;
 &lt;th&gt;Sparse score&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Nike Pegasus 40 running shoes&lt;/td&gt;
 &lt;td&gt;3.8396&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Nike Pegasus 40 womens running shoes&lt;/td&gt;
 &lt;td&gt;3.8293&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Nike Pegasus 41 running shoes&lt;/td&gt;
 &lt;td&gt;1.7007&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Sparse pushes the 41 down to third, because &lt;code&gt;40&lt;/code&gt; is a different token from &lt;code&gt;41&lt;/code&gt;. But it now has dense&amp;rsquo;s problem on a different pair: the men&amp;rsquo;s and women&amp;rsquo;s Pegasus 40 share every token the query contains, so it separates them by 0.0103 on a 3.8396 top score, roughly a quarter of a percent. Dense had those two 0.09 apart and no trouble at all.&lt;/p&gt;</description></item><item><title>Setting Up Hybrid Search in Qdrant</title><link>https://qdrant.tech/course/beginners/module-3/hybrid-search-in-qdrant/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/hybrid-search-in-qdrant/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="setting-up-hybrid-search-in-qdrant"&gt;Setting Up Hybrid Search in Qdrant&lt;/h1&gt;
&lt;p&gt;Hybrid search uses named vectors, dense and sparse on the same point, and the Query API to run a sub-query against each before fusing. A &lt;strong&gt;prefetch&lt;/strong&gt; is one of those sub-queries: it produces a candidate list that fusion then merges.&lt;/p&gt;
&lt;h3 id="step-1-create-a-hybrid-collection"&gt;Step 1: Create a Hybrid Collection&lt;/h3&gt;
&lt;p&gt;Two things are new since Module 2. The collection declares a sparse config alongside the dense one, so both vectors live on the same point. And that sparse config carries a &lt;code&gt;modifier&lt;/code&gt;, which has no dense equivalent: it tells Qdrant to compute the second half of the BM25 score at query time, the inverse document frequency. That half is what makes a rare token like &lt;code&gt;40&lt;/code&gt; outweigh a common one like &lt;code&gt;shoes&lt;/code&gt;, so without it BM25 scoring is wrong rather than merely untuned. miniCOIL needs the same modifier.&lt;/p&gt;</description></item><item><title>Fusion Strategies</title><link>https://qdrant.tech/course/beginners/module-3/fusion-strategies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/fusion-strategies/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="fusion-strategies"&gt;Fusion Strategies&lt;/h1&gt;
&lt;p&gt;The difference between the two strategies is what each does with magnitude. RRF knows only that a document came first, second, or third, so a runaway top match and a photo finish look identical to it. DBSF rescales each retriever&amp;rsquo;s scores onto a comparable range before combining them, which keeps that information at the cost of depending on how those scores are distributed.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Strategy&lt;/th&gt;
 &lt;th&gt;How it works&lt;/th&gt;
 &lt;th&gt;When to use it&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;RRF (Reciprocal Rank Fusion)&lt;/td&gt;
 &lt;td&gt;Merges by rank position, discarding raw scores&lt;/td&gt;
 &lt;td&gt;The default, and the safe choice whenever the two score scales differ, which is nearly always&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;DBSF (Distribution-Based Score Fusion)&lt;/td&gt;
 &lt;td&gt;Normalizes each retriever&amp;rsquo;s score distribution, then combines&lt;/td&gt;
 &lt;td&gt;When the size of the gaps between scores carries information worth keeping&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Neither reliably beats the other, so treat the choice as an evaluation result rather than a preference: start with RRF and switch only after measuring on a set of queries with known-good answers. The &lt;a href="https://qdrant.tech/documentation/search/hybrid-queries/"&gt;Hybrid Queries documentation&lt;/a&gt; covers both, along with their tuning parameters.&lt;/p&gt;</description></item><item><title>Filtering: Works with Any Retrieval Method</title><link>https://qdrant.tech/course/beginners/module-3/filtering/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/filtering/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="filtering-works-with-any-retrieval-method"&gt;Filtering: Works with Any Retrieval Method&lt;/h1&gt;
&lt;p&gt;Payload filters are not a hybrid-only feature. The same conditions apply to dense-only, sparse-only, and hybrid retrieval, and Qdrant evaluates them during the search rather than after it, so a filtered search still returns a full result set. What changes is &lt;em&gt;where&lt;/em&gt; the filter goes.&lt;/p&gt;
&lt;p&gt;Take the constraints a real shopper has: in stock, and available in their size.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;shopper_filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;must&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FieldCondition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;in_stock&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MatchValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FieldCondition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sizes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MatchValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;sizes&lt;/code&gt; is a list on each point, and &lt;code&gt;MatchValue&lt;/code&gt; on a list matches when any element matches, so this reads as &amp;ldquo;size 11 is among the sizes stocked&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Knowledge Check</title><link>https://qdrant.tech/course/beginners/module-3/knowledge-check/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/knowledge-check/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="knowledge-check"&gt;Knowledge Check&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Q: A shopper searches your catalog for &lt;code&gt;iPad Air&lt;/code&gt;, and dense-only search returns &lt;code&gt;iPad Mini&lt;/code&gt; first. Both are reasonable matches for the words, but the ranking is wrong. What would you add, and why would it fix this specific failure?&lt;/strong&gt;&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Show answer&lt;/summary&gt;
&lt;p&gt;Add sparse (BM25) retrieval alongside dense, combined through hybrid search. Dense embeds the whole phrase into one vector, so &amp;ldquo;Air&amp;rdquo; and &amp;ldquo;Mini&amp;rdquo; barely move the score, the same failure mode as Pegasus 40 versus 41. Sparse treats &amp;ldquo;Air&amp;rdquo; and &amp;ldquo;Mini&amp;rdquo; as distinct tokens with no relationship, so it separates the two products cleanly. Hybrid fusion lets the sparse side catch what dense alone misses.&lt;/p&gt;</description></item><item><title>References and Further Reading</title><link>https://qdrant.tech/course/beginners/module-3/references-and-further-reading/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>info@qdrant.tech (Andrey Vasnetsov)</author><guid>https://qdrant.tech/course/beginners/module-3/references-and-further-reading/</guid><description>&lt;div class="date"&gt;
 &lt;img class="date-icon" src="https://qdrant.tech/icons/outline/date-blue.svg" alt="Calendar" /&gt; Module 3 
&lt;/div&gt;

&lt;h1 id="references-and-further-reading"&gt;References and Further Reading&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://qdrant.tech/documentation/search/hybrid-queries/"&gt;Hybrid Queries&lt;/a&gt;: prefetch semantics, both fusion strategies, and their tuning parameters.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qdrant.tech/articles/sparse-vectors/"&gt;Understanding SPLADE and Sparse Vectors&lt;/a&gt;: how sparse vectors work and how SPLADE compares to BM25.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qdrant.tech/articles/minicoil/"&gt;miniCOIL: Sparse Neural Retrieval&lt;/a&gt;: why miniCOIL exists and how it extends BM25 with contextual meaning.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qdrant.tech/documentation/search/filtering/"&gt;Filtering&lt;/a&gt;: full filter syntax and the payload index each condition needs.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qdrant.tech/documentation/manage-data/vectors/#named-vectors"&gt;Named Vectors&lt;/a&gt;: configuring and querying more than one vector on a single point.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="whats-next-module-4"&gt;What&amp;rsquo;s Next: Module 4&lt;/h2&gt;
&lt;p&gt;Eight products rebuild in seconds. On a collection that takes hours to embed, one wrong decision means embedding everything again.&lt;/p&gt;</description></item></channel></rss>