<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sabrina</title>
    <description>The latest articles on DEV Community by Sabrina (@sabrinaesaquino).</description>
    <link>https://dev.to/sabrinaesaquino</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1024677%2F46882f41-ef88-4683-8e6a-2bcc01f51cac.jpg</url>
      <title>DEV Community: Sabrina</title>
      <link>https://dev.to/sabrinaesaquino</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sabrinaesaquino"/>
    <language>en</language>
    <item>
      <title>Conjuring Cursed Halloween Tales with Qdrant's Dark Arts</title>
      <dc:creator>Sabrina</dc:creator>
      <pubDate>Thu, 31 Oct 2024 15:58:13 +0000</pubDate>
      <link>https://dev.to/sabrinaesaquino/conjuring-cursed-halloween-tales-with-qdrants-dark-arts-3eji</link>
      <guid>https://dev.to/sabrinaesaquino/conjuring-cursed-halloween-tales-with-qdrants-dark-arts-3eji</guid>
      <description>&lt;p&gt;It’s finally Halloween!! 🎃 &lt;/p&gt;

&lt;p&gt;That time of the year for carved pumpkins, sexy costumes, and eerie stories whispered around a flickering candle.&lt;/p&gt;

&lt;p&gt;But if you’re like me, you never quite remember any creepy tales when you need them the most. So I thought, why not create a tool that can go through a massive collection of stories and really pick the ones that can really give us the chills.&lt;/p&gt;

&lt;p&gt;So that’s exactly what we’re building today.&lt;/p&gt;

&lt;p&gt;The plan is simple. &lt;/p&gt;

&lt;p&gt;We’ll take a dataset of Reddit Horror Stories, embed it, and set up a Qdrant collection to search through it based on themes, atmosphere, etc. Essentially, capturing the “vibe” like ‘haunted house’ or ‘creepy forest.’&lt;/p&gt;

&lt;p&gt;I’ll show all the steps you'll need to build an app like this: setting up the vector database, embedding and indexing the data, and conjuring the most cursed Halloween tales. &lt;/p&gt;

&lt;p&gt;So let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Install the Libraries
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr24ycn563ule2tubop0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr24ycn563ule2tubop0.png" alt="Astronaut Craving Pumpkings" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First things first, let's start by installing the tools we'll be using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;qdrant-client sentence_transformers datasets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Download the Dataset
&lt;/h2&gt;

&lt;p&gt;We'll be using the &lt;a href="https://huggingface.co/datasets/intone/horror_stories_reddit" rel="noopener noreferrer"&gt;Reddit horror stories dataset&lt;/a&gt;. Let's download it using the datasets library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dataset&lt;/span&gt;

&lt;span class="n"&gt;ds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intone/horror_stories_reddit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Load the Embedding Model
&lt;/h2&gt;

&lt;p&gt;We'll use the &lt;code&gt;sentence_transformers&lt;/code&gt; library to help us embed our data with the model &lt;code&gt;all-MiniLM-L6-v2&lt;/code&gt;. Here's how we'll set it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sentence-transformers/all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have a GPU available and want to speed things up, simply change it to &lt;code&gt;device='cuda:0'&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Create the Embeddings
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsoap3e4427cuf1ls6ff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsoap3e4427cuf1ls6ff.png" alt="Astronaut with a Marshmellow" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;generate_embeddings_direct&lt;/code&gt; function processes the dataset part (like "train") by breaking it into smaller groups called batches, based on the specified &lt;code&gt;batch_size&lt;/code&gt;. This helps manage memory efficiently.&lt;/p&gt;

&lt;p&gt;For each batch, the function extracts a set of sentences (e.g., 32 at a time) and uses the loaded embedding model to embed them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tqdm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tqdm&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_embeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;split_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data_split&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data_split&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;tqdm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Generating embeddings for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;split_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; split&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pbar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;batch_sentences&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;batch_embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch_sentences&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch_embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;pbar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch_sentences&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It immediately adds them in a new column in the dataset. This way, the function efficiently updates the dataset without overloading memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;train_embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_embeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;train&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;train&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;train&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;add_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;embeddings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train_embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Set up a Client
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F64ofopknwdwcwpwsg5iv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F64ofopknwdwcwpwsg5iv.png" alt="Astronaut and Ghost" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can start our Qdrant Client. If you’re working locally, just connect to the default endpoint and you’re good to go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;qdrant_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;QdrantClient&lt;/span&gt;

&lt;span class="c1"&gt;# Connecting to a locally running instance
&lt;/span&gt;&lt;span class="n"&gt;qdrant_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;QdrantClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:6333&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple enough, right? But in the real world, you’re likely working in the cloud. That means getting your &lt;a href="https://cloud.qdrant.io/" rel="noopener noreferrer"&gt;Qdrant Cloud&lt;/a&gt; instance set up and authenticated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud Setup
&lt;/h3&gt;

&lt;p&gt;To connect to your cloud instance, you’ll need the instance URL and an API key. Here’s how to do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;qdrant_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;QdrantClient&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the client with the Qdrant Cloud URL and API key
&lt;/span&gt;&lt;span class="n"&gt;qdrant_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;QdrantClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://YOUR_CLOUD_INSTANCE_ID.aws.qdrant.tech&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Replace with your cloud instance URL
&lt;/span&gt;    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Replace with your API key
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to replace &lt;code&gt;YOUR_CLOUD_INSTANCE_ID&lt;/code&gt; with your actual instance ID and &lt;code&gt;YOUR_API_KEY&lt;/code&gt; with the API key you created. You’ll find these in your Qdrant Cloud Console.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Create a Collection
&lt;/h2&gt;

&lt;p&gt;A collection in Qdrant is like a mini-database optimized for storing and querying vectors. When defining one, we need to set the size of our vectors and the metric to measure similarity. Here’s what that setup might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;qdrant_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;halloween&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Creating a collection to hold vectors for product features
&lt;/span&gt;&lt;span class="n"&gt;qdrant_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;vectors_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;VectorParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;384&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Distance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COSINE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We defined a collection &lt;code&gt;halloween&lt;/code&gt; with 384-dimensional vectors which is the size of the &lt;code&gt;all-MiniLM-L6-v2&lt;/code&gt; embeddings. Cosine distance is used here as our similarity metric. Depending on your data and use case, you might want to use different distance metrics like &lt;code&gt;Distance.EUCLID&lt;/code&gt; or &lt;code&gt;Distance.DOT&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Load the Vectors
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptvofnozzprd7t53nz68.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptvofnozzprd7t53nz68.png" alt="Astronaut Eating Apples" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Collections are nothing without data. It’s time to insert the embeddings we created earlier into it. Here’s a strategy to load embeddings in batches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;batched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;islice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;

&lt;span class="n"&gt;batch_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="n"&gt;current_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="c1"&gt;# Initialize a counter
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;batched&lt;/code&gt; function divides an iterable into smaller chunks of size &lt;code&gt;n&lt;/code&gt;. It uses &lt;code&gt;islice&lt;/code&gt; to extract consecutive elements and yields each chunk until the dataset is fully processed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;itertools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;islice&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;batched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;train&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Generate a list of IDs using the counter
&lt;/span&gt;    &lt;span class="n"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

    &lt;span class="c1"&gt;# Update the counter to continue from the next ID after the batch
&lt;/span&gt;    &lt;span class="n"&gt;current_id&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;vectors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;embeddings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;qdrant_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Batch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;vectors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vectors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;payloads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each batch is sent to Qdrant using the &lt;code&gt;upsert&lt;/code&gt; method, which inserts the batch of data. The upsert method takes a collection of IDs, vectors, and remaining item data (payloads) to store or update in the Qdrant collection.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Conjuring the Cursed Tales
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u3jloi5qhmmtc29ksjw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u3jloi5qhmmtc29ksjw.png" alt="Astronault in Candle Lights" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, it's time. &lt;/p&gt;

&lt;p&gt;With everything set up, it’s time to see if our horror story search tool can deliver some real scares. Let’s try searching for a theme like &lt;code&gt;“creepy clown”&lt;/code&gt; and see what we get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;textwrap&lt;/span&gt;

&lt;span class="c1"&gt;# Function to wrap and print long text
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_wrapped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;wrapped_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;textwrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wrapped_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Search result query
&lt;/span&gt;&lt;span class="n"&gt;search_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qdrant_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query_points&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;creepy clown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Access the first result
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;search_result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;tale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;search_result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;points&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Pretty-print the payload
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ID:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Score:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Original:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;isOriginal&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;N/A&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# Print specific payload fields
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Title:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;N/A&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Author:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;N/A&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Subreddit:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;subreddit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;N/A&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;URL:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;N/A&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# Print the text of the story separately with word wrapping for readability
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Story Text:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print_wrapped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;No text available&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No results found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result popped up, and there it was: a story titled “Sneaky Peeky.”&lt;/p&gt;

&lt;p&gt;And honestly, it was CREEPY. &lt;/p&gt;

&lt;p&gt;Whether it’s based on a true story or not? Honestly, I don’t know. It leaves you with that lingering unease like something’s watching. It's quite long, so I won't post it here, but if you want to see for yourself, go ahead—run the program and try it. &lt;/p&gt;

&lt;p&gt;You can explore any other atmosphere: “haunted house,” “creepy forest,” “possessed doll,” or whatever you’re in the mood for. Who knows? You might find something even creepier. &lt;/p&gt;

&lt;p&gt;If you do, please post it in the comments. I’d love to see what else this thing can discover.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Thanks for sticking with me through this Halloween experiment! If you’ve followed along, you’ve now taken your first step into the world of vector search and learned how to find stories that feel creepy rather than just containing spooky words.&lt;/p&gt;

&lt;p&gt;If you’re ready to go into the dark arts of vector search, there are lots of more advanced topics you can explore, like &lt;a href="https://qdrant.tech/documentation/concepts/collections/?q=multitenancy" rel="noopener noreferrer"&gt;multitenancy&lt;/a&gt;, &lt;a href="https://qdrant.tech/documentation/concepts/payload/" rel="noopener noreferrer"&gt;payload structures&lt;/a&gt;, and &lt;a href="https://qdrant.tech/documentation/tutorials/bulk-upload/" rel="noopener noreferrer"&gt;bulk upload&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;So, go ahead, and see just how deep you can go.&lt;/p&gt;

&lt;p&gt;Happy hunting! 👻&lt;/p&gt;

</description>
      <category>qdrant</category>
      <category>halloween</category>
      <category>tutorial</category>
      <category>ai</category>
    </item>
    <item>
      <title>What is Vector Quantization?</title>
      <dc:creator>Sabrina</dc:creator>
      <pubDate>Fri, 27 Sep 2024 16:14:21 +0000</pubDate>
      <link>https://dev.to/qdrant/what-is-vector-quantization-nna</link>
      <guid>https://dev.to/qdrant/what-is-vector-quantization-nna</guid>
      <description>&lt;p&gt;Vector quantization is a data compression technique used to reduce the size of high-dimensional data. Compressing vectors reduces memory usage while maintaining nearly all of the essential information. This method allows for more efficient storage and faster search operations, particularly in large datasets.&lt;/p&gt;

&lt;p&gt;When working with high-dimensional vectors, such as embeddings from providers like OpenAI, a single 1536-dimensional vector requires &lt;strong&gt;6 KB of memory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyngfp8rta3lrolbsq7um.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyngfp8rta3lrolbsq7um.png" alt="1536 dimentional vector of 6KB of size" width="742" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With 1 million vectors needing around 6 GB of memory, as your dataset grows to multiple &lt;strong&gt;millions of vectors&lt;/strong&gt;, the memory and processing demands increase significantly.&lt;/p&gt;

&lt;p&gt;To understand why this process is so computationally demanding, let's take a look at the nature of the &lt;a href="https://qdrant.tech/documentation/concepts/indexing/#vector-index" rel="noopener noreferrer"&gt;HNSW index&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;HNSW (Hierarchical Navigable Small World) index&lt;/strong&gt; organizes vectors in a layered graph, connecting each vector to its nearest neighbors. At each layer, the algorithm narrows down the search area until it reaches the lower layers, where it efficiently finds the closest matches to the query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxme94wiq18xae15xqup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxme94wiq18xae15xqup.png" alt="HNSW representation" width="723" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each time a new vector is added, the system must determine its position in the existing graph, a process similar to searching. This makes both inserting and searching for vectors complex operations.&lt;/p&gt;

&lt;p&gt;One of the key challenges with the HNSW index is that it requires a lot of &lt;strong&gt;random reads&lt;/strong&gt; and &lt;strong&gt;sequential traversals&lt;/strong&gt; through the graph. This makes the process computationally expensive, especially when you're dealing with millions of high-dimensional vectors.&lt;/p&gt;

&lt;p&gt;The system has to jump between various points in the graph in an unpredictable manner. This unpredictability makes optimization difficult, and as the dataset grows, the memory and processing requirements increase significantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvu4zkyo9st9j55s2j59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvu4zkyo9st9j55s2j59.png" alt="HNSW random searches example" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since vectors need to be stored in &lt;strong&gt;fast storage&lt;/strong&gt; like &lt;strong&gt;RAM&lt;/strong&gt; or &lt;strong&gt;SSD&lt;/strong&gt; for low-latency searches, as the size of the data grows, so does the cost of storing and processing it efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quantization&lt;/strong&gt; offers a solution by compressing vectors to smaller memory sizes, making the process more efficient.&lt;/p&gt;

&lt;p&gt;There are several methods to achieve this, and here we will focus on three main ones:&lt;/p&gt;

&lt;p&gt;&lt;a href="/articles_data/what-is-vector-quantization/types-of-quant.png" class="article-body-image-wrapper"&gt;&lt;img src="/articles_data/what-is-vector-quantization/types-of-quant.png" alt="Types of Quantization: 1. Scalar Quantization, 2. Product Quantization, 3. Binary Quantization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What is Scalar Quantization?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflk1e2v73ih1jcrdssqb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflk1e2v73ih1jcrdssqb.png" alt="Astronaut holding cube" width="800" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Qdrant, each dimension is represented by a &lt;code&gt;float32&lt;/code&gt; value, which uses &lt;strong&gt;4 bytes&lt;/strong&gt; of memory. When using &lt;a href="https://qdrant.tech/documentation/guides/quantization/#scalar-quantization" rel="noopener noreferrer"&gt;Scalar Quantization&lt;/a&gt;, we map our vectors to a range that the smaller &lt;code&gt;int8&lt;/code&gt; type can represent. An &lt;code&gt;int8&lt;/code&gt; is only &lt;strong&gt;1 byte&lt;/strong&gt; and can represent 256 values (from -128 to 127, or 0 to 255). This results in a &lt;strong&gt;75% reduction&lt;/strong&gt; in memory size.&lt;/p&gt;

&lt;p&gt;For example, if our data lies in the range of -1.0 to 1.0, Scalar Quantization will transform these values to a range that &lt;code&gt;int8&lt;/code&gt; can represent, i.e., within -128 to 127. The system &lt;strong&gt;maps&lt;/strong&gt; the &lt;code&gt;float32&lt;/code&gt; values into this range.&lt;/p&gt;

&lt;p&gt;Here's a simple linear example of what this process looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdax8eqlo5jw8sgam7qli.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdax8eqlo5jw8sgam7qli.png" alt="Scalar Quantization example" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To set up Scalar Quantization in Qdrant, you need to include the &lt;code&gt;quantization_config&lt;/code&gt; section when creating or updating a collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /collections/{collection_name}
{
    "vectors": {
      "size": 128,
      "distance": "Cosine"
    },
    "quantization_config": {
        "scalar": {
            "type": "int8",
            "quantile": 0.99,
            "always_ram": true
        }
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;quantile&lt;/code&gt; parameter is used to calculate the quantization bounds. For example, if you specify a &lt;code&gt;0.99&lt;/code&gt; quantile, the most extreme 1% of values will be excluded from the quantization bounds.&lt;/p&gt;

&lt;p&gt;This parameter only affects the resulting precision, not the memory footprint. You can adjust it if you experience a significant decrease in search quality.&lt;/p&gt;

&lt;p&gt;Scalar Quantization is a great choice if you're looking to boost search speed and compression without losing much accuracy. It also slightly improves performance, as distance calculations (such as dot product or cosine similarity) using &lt;code&gt;int8&lt;/code&gt; values are computationally simpler than using &lt;code&gt;float32&lt;/code&gt; values.&lt;/p&gt;

&lt;p&gt;While the performance gains of Scalar Quantization may not match those achieved with Binary Quantization (which we'll discuss later), it remains an excellent default choice when Binary Quantization isn’t suitable for your use case.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. What is Binary Quantization?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkav5g7facj83ggyugpan.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkav5g7facj83ggyugpan.png" alt="Astronaut in surreal white environment" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qdrant.tech/documentation/guides/quantization/#binary-quantization" rel="noopener noreferrer"&gt;Binary Quantization&lt;/a&gt; is an excellent option if you're looking to &lt;strong&gt;reduce memory&lt;/strong&gt; usage while also achieving a significant &lt;strong&gt;boost in speed&lt;/strong&gt;. It works by converting high-dimensional vectors into simple binary (0 or 1) representations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Values greater than zero are converted to 1.&lt;/li&gt;
&lt;li&gt;Values less than or equal to zero are converted to 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's consider our initial example of a 1536-dimensional vector that requires &lt;strong&gt;6 KB&lt;/strong&gt; of memory (4 bytes for each &lt;code&gt;float32&lt;/code&gt; value).&lt;/p&gt;

&lt;p&gt;After Binary Quantization, each dimension is reduced to 1 bit (1/8 byte), so the memory required is:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1536 dimensions8 bits per byte=192 bytes
\frac{1536 \text{ dimensions}}{8 \text{ bits per byte}} = 192 \text{ bytes}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;8&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt; bits per byte&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1536&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt; dimensions&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;192&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt; bytes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;



&lt;p&gt;This leads to a &lt;strong&gt;32x&lt;/strong&gt; memory reduction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxrq191v6pv8mqa21jzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxrq191v6pv8mqa21jzg.png" alt="Binary Quantization example" width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Qdrant automates the Binary Quantization process during indexing. As vectors are added to your collection, each 32-bit floating-point component is converted into a binary value according to the configuration you define.&lt;/p&gt;

&lt;p&gt;Here’s how you can set it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /collections/{collection_name}
{
    "vectors": {
      "size": 1536,
      "distance": "Cosine"
    },
    "quantization_config": {
        "binary": {
            "always_ram": true
        }
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Binary Quantization is by far the quantization method that provides the most significant processing &lt;strong&gt;speed gains&lt;/strong&gt; compared to Scalar and Product Quantizations. This is because the binary representation allows the system to use highly optimized CPU instructions, such as &lt;a href="https://en.wikipedia.org/wiki/XOR_gate#:~:text=XOR%20represents%20the%20inequality%20function,the%20other%20but%20not%20both%22" rel="noopener noreferrer"&gt;XOR&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Hamming_weight" rel="noopener noreferrer"&gt;Popcount&lt;/a&gt;, for fast distance computations.&lt;/p&gt;

&lt;p&gt;It can speed up search operations by &lt;strong&gt;up to 40x&lt;/strong&gt;, depending on the dataset and hardware.&lt;/p&gt;

&lt;p&gt;Not all models are equally compatible with Binary Quantization, and in the comparison above, we are only using models that are compatible. Some models may experience a greater loss in accuracy when quantized. We recommend using Binary Quantization with models that have &lt;strong&gt;at least 1024 dimensions&lt;/strong&gt; to minimize accuracy loss.&lt;/p&gt;

&lt;p&gt;The models that have shown the best compatibility with this method include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI text-embedding-ada-002&lt;/strong&gt; (1536 dimensions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cohere AI embed-english-v2.0&lt;/strong&gt; (4096 dimensions)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These models demonstrate minimal accuracy loss while still benefiting from substantial speed and memory gains.&lt;/p&gt;

&lt;p&gt;Even though Binary Quantization is incredibly fast and memory-efficient, the trade-offs are in &lt;strong&gt;precision&lt;/strong&gt; and &lt;strong&gt;model compatibility&lt;/strong&gt;, so you may need to ensure search quality using techniques like oversampling and rescoring.&lt;/p&gt;

&lt;p&gt;If you're interested in exploring Binary Quantization in more detail—including implementation examples, benchmark results, and usage recommendations—check out our dedicated article on &lt;a href="https://qdrant.tech/articles/binary-quantization/" rel="noopener noreferrer"&gt;Binary Quantization - Vector Search, 40x Faster&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. What is Product Quantization?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdefp3dfh6s565lpls7wx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdefp3dfh6s565lpls7wx.png" alt="Astronaut with centroids" width="800" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qdrant.tech/documentation/guides/quantization/#product-quantization" rel="noopener noreferrer"&gt;Product Quantization&lt;/a&gt; is a method used to compress high-dimensional vectors by representing them with a smaller set of representative points.&lt;/p&gt;

&lt;p&gt;The process begins by splitting the original high-dimensional vectors into smaller &lt;strong&gt;sub-vectors.&lt;/strong&gt; Each sub-vector represents a segment of the original vector, capturing different characteristics of the data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjy9jtvmlsn8pqr93xtwp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjy9jtvmlsn8pqr93xtwp.png" alt="Creation of the Sub-vector" width="800" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For each sub-vector, a separate &lt;strong&gt;codebook&lt;/strong&gt; is created, representing regions in the data space where common patterns occur.&lt;/p&gt;

&lt;p&gt;The codebook in Qdrant is trained automatically during the indexing process. As vectors are added to the collection, Qdrant uses your specified quantization settings in the &lt;code&gt;quantization_config&lt;/code&gt; to build the codebook and quantize the vectors. Here’s how you can set it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /collections/{collection_name}
{
    "vectors": {
      "size": 1024,
      "distance": "Cosine"
    },
    "quantization_config": {
        "product": {
            "compression": "x32",
            "always_ram": true
        }
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each region in the codebook is defined by a &lt;strong&gt;centroid&lt;/strong&gt;, which serves as a representative point summarizing the characteristics of that region. Instead of treating every single data point as equally important, we can group similar sub-vectors together and represent them with a single centroid that captures the general characteristics of that group.&lt;/p&gt;

&lt;p&gt;The centroids used in Product Quantization are determined using the &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/K-means_clustering" rel="noopener noreferrer"&gt;K-means clustering algorithm&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe4sgobztmeyzsv31kd2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe4sgobztmeyzsv31kd2g.png" alt="Codebook and Centroids example" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Qdrant always selects &lt;strong&gt;K = 256&lt;/strong&gt; as the number of centroids in its implementation, based on the fact that 256 is the maximum number of unique values that can be represented by a single byte.&lt;/p&gt;

&lt;p&gt;This makes the compression process efficient because each centroid index can be stored in a single byte.&lt;/p&gt;

&lt;p&gt;The original high-dimensional vectors are quantized by mapping each sub-vector to the nearest centroid in its respective codebook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7zjbzxr5tr7xwnge3xu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7zjbzxr5tr7xwnge3xu.png" alt="Vectors being mapped to their corresponding centroids example" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The compressed vector stores the index of the closest centroid for each sub-vector.&lt;/p&gt;

&lt;p&gt;Here’s how a 1024-dimensional vector, originally taking up 4096 bytes, is reduced to just 128 bytes by representing it as 128 indexes, each pointing to the centroid of a sub-vector:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp37escdizqs8srip6pr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp37escdizqs8srip6pr2.png" alt="Product Quantization example" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After setting up quantization and adding your vectors, you can perform searches as usual. Qdrant will automatically use the quantized vectors, optimizing both speed and memory usage. Optionally, you can enable rescoring for better accuracy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /collections/{collection_name}/points/search
{
    "query": [0.22, -0.01, -0.98, 0.37],
    "params": {
        "quantization": {
            "rescore": true
        }
    },
    "limit": 10
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Product Quantization can significantly reduce memory usage, potentially offering up to &lt;strong&gt;64x&lt;/strong&gt; compression in certain configurations. However, it's important to note that this level of compression can lead to a noticeable drop in quality.&lt;/p&gt;

&lt;p&gt;If your application requires high precision or real-time performance, Product Quantization may not be the best choice. However, if &lt;strong&gt;memory savings&lt;/strong&gt; are critical and some accuracy loss is acceptable, it could still be an ideal solution.&lt;/p&gt;

&lt;p&gt;Here’s a comparison of speed, accuracy, and compression for all three methods, adapted from &lt;a href="https://qdrant.tech/documentation/guides/quantization/#how-to-choose-the-right-quantization-method" rel="noopener noreferrer"&gt;Qdrant's documentation&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Quantization method&lt;/th&gt;
&lt;th&gt;Accuracy&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;th&gt;Compression&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scalar&lt;/td&gt;
&lt;td&gt;0.99&lt;/td&gt;
&lt;td&gt;up to x2&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product&lt;/td&gt;
&lt;td&gt;0.7&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;up to 64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary&lt;/td&gt;
&lt;td&gt;0.95*&lt;/td&gt;
&lt;td&gt;up to x40&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;* - for compatible models&lt;/p&gt;

&lt;p&gt;For a more in-depth understanding of the benchmarks you can expect, check out our dedicated article on &lt;a href="https://qdrant.tech/articles/product-quantization/" rel="noopener noreferrer"&gt;Product Quantization in Vector Search&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rescoring, Oversampling, and Reranking
&lt;/h2&gt;

&lt;p&gt;When we use quantization methods like Scalar, Binary, or Product Quantization, we're compressing our vectors to save memory and improve performance. However, this compression removes some detail from the original vectors.&lt;/p&gt;

&lt;p&gt;This can slightly reduce the accuracy of our similarity searches because the quantized vectors are approximations of the original data. To mitigate this loss of accuracy, you can use &lt;strong&gt;oversampling&lt;/strong&gt; and &lt;strong&gt;rescoring&lt;/strong&gt;, which help improve the accuracy of the final search results.&lt;/p&gt;

&lt;p&gt;The original vectors are never deleted during this process, and you can easily switch between quantization methods or parameters by updating the collection configuration at any time.&lt;/p&gt;

&lt;p&gt;Here’s how the process works, step by step:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Initial Quantized Search
&lt;/h3&gt;

&lt;p&gt;When you perform a search, Qdrant retrieves the top candidates using the quantized vectors based on their similarity to the query vector, as determined by the quantized data. This step is fast because we're using the quantized vectors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkzu1flsaiy7pmwwqgyt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkzu1flsaiy7pmwwqgyt.png" alt="ANN Search with Quantization" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Oversampling
&lt;/h3&gt;

&lt;p&gt;Oversampling is a technique that helps compensate for any precision lost due to quantization. Since quantization simplifies vectors, some relevant matches could be missed in the initial search. To avoid this, you can &lt;strong&gt;retrieve more candidates&lt;/strong&gt;, increasing the chances that the most relevant vectors make it into the final results.&lt;/p&gt;

&lt;p&gt;You can control the number of extra candidates by setting an &lt;code&gt;oversampling&lt;/code&gt; parameter. For example, if your desired number of results (&lt;code&gt;limit&lt;/code&gt;) is 4 and you set an &lt;code&gt;oversampling&lt;/code&gt; factor of 2, Qdrant will retrieve 8 candidates (4 × 2).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjv52syp3swcfq5m2f9v7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjv52syp3swcfq5m2f9v7.png" alt="ANN Search with Quantization and Oversampling" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can adjust the oversampling factor to control how many extra vectors Qdrant includes in the initial pool. More candidates mean a better chance of obtaining high-quality top-K results, especially after rescoring with the original vectors.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Rescoring with Original Vectors
&lt;/h3&gt;

&lt;p&gt;After oversampling to gather more potential matches, each candidate is re-evaluated based on additional criteria to ensure higher accuracy and relevance to the query.&lt;/p&gt;

&lt;p&gt;The rescoring process &lt;strong&gt;maps&lt;/strong&gt; the quantized vectors to their corresponding original vectors, allowing you to consider factors like context, metadata, or additional relevance that wasn’t included in the initial search, leading to more accurate results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xofzja0fqb4xutgqqaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xofzja0fqb4xutgqqaz.png" alt="Rescoring with Original Vectors" width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During rescoring, one of the lower-ranked candidates from oversampling might turn out to be a better match than some of the original top-K candidates.&lt;/p&gt;

&lt;p&gt;Even though rescoring uses the original, larger vectors, the process remains much faster because only a very small number of vectors are read. The initial quantized search already identifies the specific vectors to read, rescore, and rerank.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Reranking
&lt;/h3&gt;

&lt;p&gt;With the new similarity scores from rescoring, &lt;strong&gt;reranking&lt;/strong&gt; is where the final top-K candidates are determined based on the updated similarity scores.&lt;/p&gt;

&lt;p&gt;For example, in our case with a limit of 4, a candidate that ranked 6th in the initial quantized search might improve its score after rescoring because the original vectors capture more context or metadata. As a result, this candidate could move into the final top 4 after reranking, replacing a less relevant option from the initial search.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff45cru5len2fprc22rx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff45cru5len2fprc22rx9.png" alt="Reranking with Original Vectors" width="800" height="610"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's how you can set it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /collections/{collection_name}/points/search
{
  "query": [0.22, -0.01, -0.98, 0.37],
  "params": {
    "quantization": {
      "rescore": true,
      "oversampling": 2
    }
  },
  "limit": 4
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can adjust the &lt;code&gt;oversampling&lt;/code&gt; factor to find the right balance between search speed and result accuracy.&lt;/p&gt;

&lt;p&gt;If quantization is impacting performance in an application that requires high accuracy, combining oversampling with rescoring is a great choice. However, if you need faster searches and can tolerate some loss in accuracy, you might choose to use oversampling without rescoring, or adjust the oversampling factor to a lower value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Distributing Resources Between Disk &amp;amp; Memory
&lt;/h2&gt;

&lt;p&gt;Qdrant stores both the quantized and original vectors. When you enable quantization, both the original and quantized vectors are stored in RAM by default. You can move the original vectors to disk to significantly reduce RAM usage and lower system costs. Simply enabling quantization is not enough—you need to explicitly move the original vectors to disk by setting &lt;code&gt;on_disk=True&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here’s an example configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /collections/{collection_name}
{
  "vectors": {
    "size": 1536,
    "distance": "Cosine",
    "on_disk": true  # Move original vectors to disk
  },
  "quantization_config": {
    "binary": {
      "always_ram": true  # Store only quantized vectors in RAM
    }
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without explicitly setting &lt;code&gt;on_disk=True&lt;/code&gt;, you won't see any RAM savings, even with quantization enabled. So, make sure to configure both storage and quantization options based on your memory and performance needs. If your storage has high disk latency, consider disabling rescoring to maintain speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speeding Up Rescoring with io_uring
&lt;/h3&gt;

&lt;p&gt;When dealing with large collections of quantized vectors, frequent disk reads are required to retrieve both original and compressed data for rescoring operations. While &lt;code&gt;mmap&lt;/code&gt; helps with efficient I/O by reducing user-to-kernel transitions, rescoring can still be slowed down when working with large datasets on disk due to the need for frequent disk reads.&lt;/p&gt;

&lt;p&gt;On Linux-based systems, &lt;code&gt;io_uring&lt;/code&gt; allows multiple disk operations to be processed in parallel, significantly reducing I/O overhead. This optimization is particularly effective during rescoring, where multiple vectors need to be re-evaluated after the initial search. With io_uring, Qdrant can retrieve and rescore vectors from disk in the most efficient way, improving overall search performance.&lt;/p&gt;

&lt;p&gt;When you perform vector quantization and store data on disk, Qdrant often needs to access multiple vectors in parallel. Without io_uring, this process can be slowed down due to the system’s limitations in handling many disk accesses.&lt;/p&gt;

&lt;p&gt;To enable &lt;code&gt;io_uring&lt;/code&gt; in Qdrant, add the following to your storage configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;async_scorer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;  &lt;span class="c1"&gt;# Enable io_uring for async storage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without this configuration, Qdrant will default to using &lt;code&gt;mmap&lt;/code&gt; for disk I/O operations.&lt;/p&gt;

&lt;p&gt;For more information and benchmarks comparing io_uring with traditional I/O approaches like mmap, check out &lt;a href="https://qdrant.tech/articles/io_uring/" rel="noopener noreferrer"&gt;Qdrant's io_uring implementation article.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance of Quantized vs. Non-Quantized Data
&lt;/h2&gt;

&lt;p&gt;Qdrant uses the quantized vectors by default if they are available. If you want to evaluate how quantization affects your search results, you can temporarily disable it to compare results from quantized and non-quantized searches. To do this, set &lt;code&gt;ignore: true&lt;/code&gt; in the query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /collections/{collection_name}/points/query
{
    "query": [0.22, -0.01, -0.98, 0.37],
    "params": {
        "quantization": {
            "ignore": true,
        }
    },
    "limit": 4
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Switching Between Quantization Methods
&lt;/h3&gt;

&lt;p&gt;Not sure if you’ve chosen the right quantization method? In Qdrant, you have the flexibility to remove quantization and rely solely on the original vectors, adjust the quantization type, or change compression parameters at any time without affecting your original vectors.&lt;/p&gt;

&lt;p&gt;To switch to binary quantization and adjust the compression rate, for example, you can update the collection’s quantization configuration using the &lt;code&gt;update_collection&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /collections/{collection_name}
{
  "vectors": {
    "size": 1536,
    "distance": "Cosine"
  },
  "quantization_config": {
    "binary": {
      "always_ram": true,
      "compression_rate": 0.8  # Set the new compression rate
    }
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you decide to &lt;strong&gt;turn off quantization&lt;/strong&gt; and use only the original vectors, you can remove the quantization settings entirely with &lt;code&gt;quantization_config=None&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /collections/my_collection
{
  "vectors": {
    "size": 1536,
    "distance": "Cosine"
  },
  "quantization_config": null  # Remove quantization and use original vectors only
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7b9hbwu41bmnt0141tu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7b9hbwu41bmnt0141tu1.png" alt="Astronaut leaving" width="800" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quantization methods like Scalar, Product, and Binary Quantization offer powerful ways to optimize memory usage and improve search performance when dealing with large datasets of high-dimensional vectors. Each method comes with its own trade-offs between memory savings, computational speed, and accuracy.&lt;/p&gt;

&lt;p&gt;Here are some final thoughts to help you choose the right quantization method for your needs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Quantization Method&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;When to Use&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Binary Quantization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• &lt;strong&gt;Fastest method and most memory-efficient&lt;/strong&gt;&lt;br&gt;•  Up to &lt;strong&gt;40x&lt;/strong&gt; faster search and &lt;strong&gt;32x&lt;/strong&gt; reduced memory footprint&lt;/td&gt;
&lt;td&gt;• Use with tested models like OpenAI's &lt;code&gt;text-embedding-ada-002&lt;/code&gt; and Cohere's &lt;code&gt;embed-english-v2.0&lt;/code&gt;&lt;br&gt;• When speed and memory efficiency are critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalar Quantization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• &lt;strong&gt;Minimal loss of accuracy&lt;/strong&gt;&lt;br&gt;•  Up to &lt;strong&gt;4x&lt;/strong&gt; reduced memory footprint&lt;/td&gt;
&lt;td&gt;• Safe default choice for most applications.&lt;br&gt;• Offers a good balance between accuracy, speed, and compression.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Product Quantization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• &lt;strong&gt;Highest compression ratio&lt;/strong&gt;&lt;br&gt;• Up to &lt;strong&gt;64x&lt;/strong&gt; reduced memory footprint&lt;/td&gt;
&lt;td&gt;• When minimizing memory usage is the top priority&lt;br&gt;• Acceptable if some loss of accuracy and slower indexing is tolerable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Learn More
&lt;/h3&gt;

&lt;p&gt;If you want to learn more about improving accuracy, memory efficiency, and speed when using quantization in Qdrant, we have a dedicated &lt;a href="https://qdrant.tech/documentation/guides/quantization/#quantization-tips" rel="noopener noreferrer"&gt;Quantization tips&lt;/a&gt; section in our docs that explains all the quantization tips you can use to enhance your results.&lt;/p&gt;

&lt;p&gt;Learn more about optimizing real-time precision with oversampling in Binary Quantization by watching this interview with Qdrant’s CTO, Andrey Vasnetsov:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/4aUq5VnR_VI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Stay up-to-date on the latest in &lt;a href="https://dev.to/advanced-search/"&gt;vector search&lt;/a&gt; and quantization, share your projects, ask questions, &lt;a href="https://discord.com/invite/qdrant" rel="noopener noreferrer"&gt;join our vector search community&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>machinelearning</category>
      <category>datascience</category>
    </item>
    <item>
      <title>A Complete Guide to Filtering in Vector Search</title>
      <dc:creator>Sabrina</dc:creator>
      <pubDate>Thu, 12 Sep 2024 14:45:10 +0000</pubDate>
      <link>https://dev.to/qdrant/a-complete-guide-to-filtering-in-vector-search-33lk</link>
      <guid>https://dev.to/qdrant/a-complete-guide-to-filtering-in-vector-search-33lk</guid>
      <description>&lt;p&gt;Imagine you sell computer hardware. To help shoppers easily find products on your website, you need to have a &lt;strong&gt;user-friendly &lt;a href="https://qdrant.tech" rel="noopener noreferrer"&gt;search engine&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo0vwfd8cpy0698f5mhq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo0vwfd8cpy0698f5mhq6.png" alt="vector-search-ecommerce" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re selling computers and have extensive data on laptops, desktops, and accessories, your search feature should guide customers to the exact device they want - or a &lt;strong&gt;very similar&lt;/strong&gt; match needed.&lt;/p&gt;

&lt;p&gt;When storing data in Qdrant, each product is a point, consisting of an &lt;code&gt;id&lt;/code&gt;, a &lt;code&gt;vector&lt;/code&gt; and &lt;code&gt;payload&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="nl"&gt;"vector"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;899.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"laptop"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;id&lt;/code&gt; is a unique identifier for the point in your collection. The &lt;code&gt;vector&lt;/code&gt; is a mathematical representation of similarity to other points in the collection. &lt;br&gt;
Finally, the &lt;code&gt;payload&lt;/code&gt; holds metadata that directly describes the point.&lt;/p&gt;

&lt;p&gt;Though we may not be able to decipher the vector, we are able to derive additional information about the item from its metadata, In this specific case, &lt;strong&gt;we are looking at a data point for a laptop that costs $899.99&lt;/strong&gt;. &lt;/p&gt;
&lt;h2&gt;
  
  
  What is filtering?
&lt;/h2&gt;

&lt;p&gt;When searching for the perfect computer, your customers may end up with results that are mathematically similar to the search entry, but not exact. For example, if they are searching for &lt;strong&gt;laptops under $1000&lt;/strong&gt;, a simple &lt;a href="https://dev.to/advanced-search/"&gt;vector search&lt;/a&gt; without constraints might still show other laptops over $1000. &lt;/p&gt;

&lt;p&gt;This is why &lt;a href="https://dev.to/advanced-search/"&gt;semantic search&lt;/a&gt; alone &lt;strong&gt;may not be enough&lt;/strong&gt;. In order to get the exact result, you would need to enforce a payload filter on the &lt;code&gt;price&lt;/code&gt;. Only then can you be sure that the search results abide by the chosen characteristic.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is called &lt;strong&gt;filtering&lt;/strong&gt; and it is one of the key features of &lt;a href="https://qdrant.tech" rel="noopener noreferrer"&gt;vector databases&lt;/a&gt;. &lt;br&gt;
Here is how a &lt;strong&gt;filtered vector search&lt;/strong&gt; looks behind the scenes. We'll cover its mechanics in the following section.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /collections/online_store/points/search
{
  "vector": [ 0.2, 0.1, 0.9, 0.7 ],
  "filter": {
    "must": [
      {
        "key": "category",
        "match": { "value": "laptop" }
      },
      {
        "key": "price",
        "range": {
          "gt": null,
          "gte": null,
          "lt": null,
          "lte": 1000
        }
      }
    ]
  },
  "limit": 3,
  "with_payload": true,
  "with_vector": false
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The filtered result will be a combination of the semantic search and the filtering conditions imposed upon the query. In the following pages, we will show that &lt;strong&gt;filtering is a key practice in vector search for two reasons:&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;With filtering, you can &lt;strong&gt;dramatically increase search precision&lt;/strong&gt;. More on this in the next section.&lt;/li&gt;
&lt;li&gt;Filtering helps control resources and &lt;strong&gt;reduce compute use&lt;/strong&gt;. More on this in &lt;strong&gt;Payload Indexing&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What you will learn in this guide:
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/advanced-search/"&gt;vector search&lt;/a&gt;, filtering and sorting are more interdependent than they are in traditional databases. While databases like SQL use commands such as &lt;code&gt;WHERE&lt;/code&gt; and &lt;code&gt;ORDER BY&lt;/code&gt;, the interplay between these processes in vector search is a bit more complex.&lt;/p&gt;

&lt;p&gt;Most people use default settings and build vector search apps that aren't properly configured or even setup for precise retrieval. In this guide, we will show you how to &lt;strong&gt;use filtering to get the most out of vector search&lt;/strong&gt; with some basic and advanced strategies that are easy to implement. &lt;/p&gt;

&lt;h3&gt;
  
  
  Remember to run all tutorial code in Qdrant's Dashboard
&lt;/h3&gt;

&lt;p&gt;The easiest way to reach that "Hello World" moment is to &lt;a href="https://dev.to/documentation/quickstart-cloud/"&gt;&lt;strong&gt;try filtering in a live cluster&lt;/strong&gt;&lt;/a&gt;. Our interactive tutorial will show you how to create a cluster, add data and try some filtering clauses. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyvsxdq1qtak3kxt45y6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyvsxdq1qtak3kxt45y6.png" alt="qdrant-filtering-tutorial" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Qdrant's approach to filtering
&lt;/h2&gt;

&lt;p&gt;Qdrant follows a specific method of searching and filtering through dense vectors. &lt;/p&gt;

&lt;p&gt;Let's take a look at this &lt;strong&gt;3-stage diagram&lt;/strong&gt;. In this case, we are trying to find the nearest neighbour to the query vector &lt;strong&gt;(green)&lt;/strong&gt;. Your search journey starts at the bottom &lt;strong&gt;(orange)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By default, Qdrant connects all your data points within the &lt;a href="https://dev.to/documentation/concepts/indexing/"&gt;&lt;strong&gt;vector index&lt;/strong&gt;&lt;/a&gt;. After you &lt;a href="https://dev.to/documentation/concepts/filtering/"&gt;&lt;strong&gt;introduce filters&lt;/strong&gt;&lt;/a&gt;, some data points become disconnected. Vector search can't cross the grayed out area and it won't reach the nearest neighbor. &lt;br&gt;
How can we bridge this gap? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1:&lt;/strong&gt; How Qdrant maintains a filterable vector index. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw5ev6l3u7bzp8861sfp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw5ev6l3u7bzp8861sfp.png" alt="filterable-vector-index" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/documentation/concepts/indexing/"&gt;&lt;strong&gt;Filterable vector index&lt;/strong&gt;&lt;/a&gt;: This technique builds additional links &lt;strong&gt;(orange)&lt;/strong&gt; between leftover data points. The filtered points which stay behind are now traversible once again. Qdrant uses special category-based methods to connect these data points. &lt;/p&gt;
&lt;h2&gt;
  
  
  Qdrant's approach vs traditional filtering methods
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tgwitznyx39lxze4ad1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tgwitznyx39lxze4ad1.png" alt="stepping-lens" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The filterable vector index is Qdrant's solves pre and post-filtering problems by adding specialized links to the search graph. It aims to maintain the speed advantages of vector search while allowing for precise filtering, addressing the inefficiencies that can occur when applying filters after the vector search.&lt;/p&gt;
&lt;h3&gt;
  
  
  Pre-filtering
&lt;/h3&gt;

&lt;p&gt;In pre-filtering, a search engine first narrows down the dataset based on chosen metadata values, and then searches within that filtered subset. This reduces unnecessary computation over a dataset that is potentially much larger.&lt;/p&gt;

&lt;p&gt;The choice between pre-filtering and using the filterable HNSW index depends on filter cardinality. When metadata cardinality is too low, the filter becomes restrictive and it can disrupt the connections within the graph. This leads to fragmented search paths (as in &lt;strong&gt;Figure 1&lt;/strong&gt;). When the semantic search process begins, it won’t be able to travel to those locations. &lt;/p&gt;

&lt;p&gt;However, Qdrant still benefits from pre-filtering &lt;strong&gt;under certain conditions&lt;/strong&gt;. In cases of low cardinality, Qdrant's query planner stops using HNSW and switches over to the payload index alone. This makes the search process much cheaper and faster than if using HNSW.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2:&lt;/strong&gt; On the user side, this is how filtering looks. We start with five products with different prices. First, the $1000 price &lt;strong&gt;filter&lt;/strong&gt; is applied, narrowing down the selection of laptops. Then, a vector search finds the relevant &lt;strong&gt;results&lt;/strong&gt; within this filtered set. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxomreb49ere8ow2n5d6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxomreb49ere8ow2n5d6g.png" alt="pre-filtering-vector-search" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, pre-filtering is efficient in specific cases when you use small datasets with low cardinality metadata. However, pre-filtering should not be used over large datasets as it breaks too many links in the HNSW graph, causing lower accuracy.&lt;/p&gt;
&lt;h3&gt;
  
  
  Post-filtering
&lt;/h3&gt;

&lt;p&gt;In post-filtering, a search engine first looks for similar vectors and retrieves a larger set of results. Then, it applies filters to those results based on metadata. The problem with post-filtering becomes apparent when using low-cardinality filters. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you apply a low-cardinality filter after performing a vector search, you often end up discarding a large portion of the results that the vector search returned.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Figure 3:&lt;/strong&gt; In the same example, we have five laptops. First, the vector search finds the top two relevant &lt;strong&gt;results&lt;/strong&gt;, but they may not meet the price match. When the $1000 price &lt;strong&gt;filter&lt;/strong&gt; is applied, other potential results are discarded.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqofpcv9w7q0exrq0cuot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqofpcv9w7q0exrq0cuot.png" alt="post-filtering-vector-search" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The system will waste computational resources by first finding similar vectors and then discarding many that don't meet the filter criteria. You're also limited to filtering only from the initial set of &lt;a href="https://dev.to/advanced-search/"&gt;vector search&lt;/a&gt; results. If your desired items aren't in this initial set, you won't find them, even if they exist in the database.&lt;/p&gt;
&lt;h2&gt;
  
  
  Basic filtering example: ecommerce and laptops
&lt;/h2&gt;

&lt;p&gt;We know that there are three possible laptops that suit our price point. &lt;br&gt;
Let's see how Qdrant's filterable vector index works and why it is the best method of capturing all available results.  &lt;/p&gt;

&lt;p&gt;First, add five new laptops to your online store. Here is a sample input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;laptops&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;899.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;laptop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1299.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;laptop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;799.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;laptop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1099.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;laptop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;949.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;laptop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The four-dimensional vector can represent features like laptop CPU, RAM or battery life, but that isn’t specified. The payload, however, specifies the exact price and product category.&lt;/p&gt;

&lt;p&gt;Now, set the filter to "price is less than $1000":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"gt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"gte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a price filter of equal/less than $1000 is applied, vector search returns the following results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9978443564622781&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;799.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"laptop"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9938079894227599&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;899.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"laptop"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9903751498208603&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;949.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"laptop"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, Qdrant's filtering method has a greater chance of capturing all possible search results. &lt;/p&gt;

&lt;p&gt;This specific example uses the &lt;code&gt;range&lt;/code&gt; condition for filtering. Qdrant, however, offers many other possible ways to structure a filter&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For detailed usage examples, &lt;a href="https://dev.to/documentation/concepts/filtering/"&gt;filtering&lt;/a&gt; docs are the best resource.&lt;/strong&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Scrolling instead of searching
&lt;/h2&gt;

&lt;p&gt;You don't need to use our &lt;code&gt;search&lt;/code&gt; and &lt;code&gt;query&lt;/code&gt; APIs to filter through data. The &lt;code&gt;scroll&lt;/code&gt; API is another option that lets you retrieve lists of points which meet the filters.&lt;/p&gt;

&lt;p&gt;If you aren't interested in finding similar points, you can simply list the ones that match a given filter. While search gives you the most similar points based on some query vector, scroll will give you all points matching your filter not considering similarity. &lt;/p&gt;

&lt;p&gt;In Qdrant, scrolling is used to iteratively &lt;strong&gt;retrieve large sets of points from a collection&lt;/strong&gt;. It is particularly useful when you’re dealing with a large number of points and don’t want to load them all at once. Instead, Qdrant provides a way to scroll through the points &lt;strong&gt;one page at a time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You start by sending a scroll request to Qdrant with specific conditions like filtering by payload, vector search, or other criteria.&lt;/p&gt;

&lt;p&gt;Let's retrieve a list of top 10 laptops ordered by price in the store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /collections/online_store/points/scroll
{
    "filter": {
        "must": [
            {
                "key": "category",
                "match": {
                    "value": "laptop"
                }
            }
        ]
    },
    "limit": 10,
    "with_payload": true,
    "with_vector": false,
    "order_by": [
        {
            "key": "price",
        }
    ]
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response contains a batch of points that match the criteria and a reference (offset or next page token) to retrieve the next set of points.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://dev.to/documentation/concepts/points/#scroll-points"&gt;&lt;strong&gt;Scrolling&lt;/strong&gt;&lt;/a&gt; is designed to be efficient. It minimizes the load on the server and reduces memory consumption on the client side by returning only manageable chunks of data at a time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Available filtering conditions
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Condition&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Condition&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Match&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Exact value match.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Range&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter by value range.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Match Any&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Match multiple values.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Datetime Range&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter by date range.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Match Except&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Exclude specific values.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;UUID Match&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter by unique ID.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nested Key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter by nested data.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Geo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter by location.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nested Object&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter by nested objects.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Values Count&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter by element count.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Full Text Match&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Search in text fields.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Is Empty&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter empty fields.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Has ID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter by unique ID.&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Is Null&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filter null values.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;All clauses and conditions are outlined in Qdrant's &lt;a href="https://dev.to/documentation/concepts/filtering/"&gt;filtering&lt;/a&gt; documentation. &lt;/p&gt;
&lt;h3&gt;
  
  
  Filtering clauses to remember
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Clause&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Clause&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Must&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Includes items that meet the condition  (similar to &lt;code&gt;AND&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Should&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Filters if at least one condition is met  (similar to &lt;code&gt;OR&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Must Not&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Excludes items that meet the condition  (similar to &lt;code&gt;NOT&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Clauses Combination&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Combines multiple clauses to refine filtering  (similar to &lt;code&gt;AND&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Advanced filtering example: dinosaur diets
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6wzc3g0uqu3rylr714u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6wzc3g0uqu3rylr714u.png" alt="advanced-payload-filtering" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also use nested filtering to query arrays of objects within the payload. In this example, we have two points. They each represent a dinosaur with a list of food preferences (diet) that indicate what type of food they like or dislike:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dinosaur"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"t-rex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"diet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"food"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"leaves"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"likes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"food"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"meat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"likes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dinosaur"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"diplodocus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"diet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"food"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"leaves"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"likes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"food"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"meat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"likes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure that both conditions are applied to the same array element (e.g., food = meat and likes = true must refer to the same diet item), you need to use a nested filter.&lt;/p&gt;

&lt;p&gt;Nested filters are used to apply conditions within an array of objects. They ensure that the conditions are evaluated per array element, rather than across all elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /collections/dinosaurs/points/scroll
{
    "filter": {
        "must": [
            {
                "key": "diet[].food",
                  "match": {
                    "value": "meat"
                }
            },
            {
                "key": "diet[].likes",
                  "match": {
                    "value": true
                }
            }
        ]
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dinosaurs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;scroll_filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&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 class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;diet[].food&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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="p"&gt;.&lt;/span&gt;&lt;span class="nc"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;meat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;diet[].likes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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="p"&gt;.&lt;/span&gt;&lt;span class="nc"&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="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dinosaurs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;must&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;diet[].food&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;diet[].likes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;qdrant_client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;qdrant&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScrollPointsBuilder&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;
    &lt;span class="nf"&gt;.scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nn"&gt;ScrollPointsBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dinosaurs"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;must&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="nn"&gt;Condition&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"diet[].food"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"meat"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
            &lt;span class="nn"&gt;Condition&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"diet[].likes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;])),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;qdrant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ConditionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;qdrant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ConditionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matchKeyword&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.qdrant.client.QdrantClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.qdrant.client.QdrantGrpcClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.qdrant.client.grpc.Points.Filter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.qdrant.client.grpc.Points.ScrollPoints&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;QdrantClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QdrantClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;QdrantGrpcClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6334&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scrollAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;ScrollPoints&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCollectionName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dinosaurs"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFilter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllMust&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matchKeyword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"diet[].food"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"meat"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"diet[].likes"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Qdrant.Client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Qdrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Grpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conditions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QdrantClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;6334&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ScrollAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;collectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"dinosaurs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;MatchKeyword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"diet[].food"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"meat"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"diet[].likes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This happens because both points are matching the two conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the "t-rex" matches food=meat on &lt;code&gt;diet[1].food&lt;/code&gt; and likes=true on &lt;code&gt;diet[1].likes&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the "diplodocus" matches food=meat on &lt;code&gt;diet[1].food&lt;/code&gt; and likes=true on &lt;code&gt;diet[0].likes&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To retrieve only the points where the conditions apply to a specific element within an array (such as the point with id 1 in this example), you need to use a nested object filter.&lt;/p&gt;

&lt;p&gt;Nested object filters enable querying arrays of objects independently, ensuring conditions are checked within individual array elements.&lt;/p&gt;

&lt;p&gt;This is done by using the &lt;code&gt;nested&lt;/code&gt; condition type, which consists of a payload key that targets an array and a filter to apply. The key should reference an array of objects and can be written with or without bracket notation (e.g., "data" or "data[]").&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /collections/dinosaurs/points/scroll
{
    "filter": {
        "must": [{
            "nested": {
                "key": "diet",
                "filter":{
                    "must": [
                        {
                            "key": "food",
                            "match": {
                                "value": "meat"
                            }
                        },
                        {
                            "key": "likes",
                            "match": {
                                "value": true
                            }
                        }
                    ]
                }
            }
        }]
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dinosaurs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;scroll_filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&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 class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NestedCondition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;nested&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Nested&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;diet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&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 class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;food&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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="p"&gt;.&lt;/span&gt;&lt;span class="nc"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;meat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="p"&gt;),&lt;/span&gt;
                            &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;likes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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="p"&gt;.&lt;/span&gt;&lt;span class="nc"&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="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="p"&gt;),&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dinosaurs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;must&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;nested&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;diet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;must&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;food&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;likes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;qdrant_client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;qdrant&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NestedCondition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScrollPointsBuilder&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;
    &lt;span class="nf"&gt;.scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nn"&gt;ScrollPointsBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dinosaurs"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;must&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;NestedCondition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"diet"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;must&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                &lt;span class="nn"&gt;Condition&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"food"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"meat"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
                &lt;span class="nn"&gt;Condition&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"likes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;])),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;()])),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;qdrant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ConditionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;qdrant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ConditionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matchKeyword&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;qdrant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ConditionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nested&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.qdrant.client.grpc.Points.Filter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.qdrant.client.grpc.Points.ScrollPoints&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scrollAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;ScrollPoints&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCollectionName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dinosaurs"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFilter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addMust&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;nested&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                            &lt;span class="s"&gt;"diet"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                            &lt;span class="nc"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllMust&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                                    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                                        &lt;span class="n"&gt;matchKeyword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"food"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"meat"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"likes"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
                                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Qdrant.Client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Qdrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Grpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conditions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QdrantClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;6334&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ScrollAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;collectionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"dinosaurs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Nested&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"diet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;MatchKeyword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"food"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"meat"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"likes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The matching logic is adjusted to operate at the level of individual elements within an array in the payload.&lt;/p&gt;

&lt;p&gt;Nested filters function as though each element of the array is evaluated separately. The parent document will be considered a match if at least one array element satisfies the nested filter conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other creative uses for filters
&lt;/h2&gt;

&lt;p&gt;You can use filters to retrieve data points without knowing their &lt;code&gt;id&lt;/code&gt;. You can search through data and manage it, solely by using filters. Let's take a look at some creative uses for filters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/points/#delete-points"&gt;Delete Points&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Deletes all points matching the filter.&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/payload/#set-payload"&gt;Set Payload&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Adds payload fields to all points matching the filter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/points/#scroll-points"&gt;Scroll Points&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Lists all points matching the filter.&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/payload/#overwrite-payload"&gt;Update Payload&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Updates payload fields for points matching the filter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/points/#order-points-by-payload-key"&gt;Order Points&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Lists all points, sorted by the filter.&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/payload/#delete-payload-keys"&gt;Delete Payload&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Deletes fields for points matching the filter.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/points/#counting-points"&gt;Count Points&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Totals the points matching the filter.&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Filtering with the payload index
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnetjc13aqk0wuoqxh06e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnetjc13aqk0wuoqxh06e.png" alt="vector-search-filtering-vector-search" width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you start working with Qdrant, your data is by default organized in a vector index. &lt;br&gt;
In addition to this, we recommend adding a secondary data structure - &lt;strong&gt;the payload index&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Just how the vector index organizes vectors, the payload index will structure your metadata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 4:&lt;/strong&gt; The payload index is an additional data structure that supports vector search. A payload index (in green) organizes candidate results by cardinality, so that semantic search (in red) can traverse the vector index quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffur2cj4wfc4ja57jufln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffur2cj4wfc4ja57jufln.png" alt="payload-index-vector-search" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On its own, semantic searching over terabytes of data can take up lots of RAM. &lt;a href="https://dev.to/documentation/concepts/filtering/"&gt;&lt;strong&gt;Filtering&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://dev.to/documentation/concepts/indexing/"&gt;&lt;strong&gt;Indexing&lt;/strong&gt;&lt;/a&gt; are two easy strategies to reduce your compute usage and still get the best results. Remember, this is only a guide. For an exhaustive list of filtering options, you should read the &lt;a href="https://dev.to/documentation/concepts/filtering/"&gt;filtering documentation&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Here is how you can create a single index for a metadata field "category":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /collections/computers/index
{
    "field_name": "category",
    "field_schema": "keyword"
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;qdrant_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;QdrantClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;QdrantClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:6333&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_payload_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="n"&gt;collection_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;computers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;field_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;field_schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;keyword&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you mark a field indexable, &lt;strong&gt;you don't need to do anything else&lt;/strong&gt;. Qdrant will handle all optimizations in the background.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why should you index metadata?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhez94br0kvkjiz02m74u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhez94br0kvkjiz02m74u.png" alt="payload-index-filtering" width="800" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The payload index acts as a secondary data structure that speeds up retrieval. Whenever you run vector search with a filter, Qdrant will consult a payload index - if there is one. &lt;/p&gt;

&lt;p&gt;If you are indexing your metadata, the difference in search performance can be dramatic. &lt;/p&gt;

&lt;p&gt;As your dataset grows in complexity, Qdrant takes up additional resources to go through all data points. Without a proper data structure, the search can take longer - or run out of resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payload indexing helps evaluate the most restrictive filters
&lt;/h3&gt;

&lt;p&gt;The payload index is also used to accurately estimate &lt;strong&gt;filter cardinality&lt;/strong&gt;, which helps the query planning choose a search strategy. &lt;strong&gt;Filter cardinality&lt;/strong&gt; refers to the number of distinct values that a filter can match within a dataset. Qdrant's search strategy can switch from &lt;strong&gt;HNSW search&lt;/strong&gt; to &lt;strong&gt;payload index-based search&lt;/strong&gt; if the cardinality is too low.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it affects your queries:&lt;/strong&gt; Depending on the filter used in the search - there are several possible scenarios for query execution. Qdrant chooses one of the query execution options depending on the available indexes, the complexity of the conditions and the cardinality of the filtering result. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The planner estimates the cardinality of a filtered result before selecting a strategy.&lt;/li&gt;
&lt;li&gt;Qdrant retrieves points using the &lt;strong&gt;payload index&lt;/strong&gt; if cardinality is below threshold.&lt;/li&gt;
&lt;li&gt;Qdrant uses the &lt;strong&gt;filterable vector index&lt;/strong&gt; if the cardinality is above a threshold&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What happens if you don't use payload indexes?
&lt;/h3&gt;

&lt;p&gt;If you only rely on &lt;strong&gt;searching for the nearest vector&lt;/strong&gt;, Qdrant will have to go through the entire vector index. It will calculate similarities against each vector in the collection, relevant or not. Alternatively, when you filter with the help of a payload index, the HSNW algorithm won't have to evaluate every point. Furthermore, the payload index will help HNSW  construct the graph with additional links.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the payload index look?
&lt;/h2&gt;

&lt;p&gt;A payload index is similar to conventional document-oriented databases. It connects metadata fields with their corresponding point id’s for quick retrieval. &lt;/p&gt;

&lt;p&gt;In this example, you are indexing all of your computer hardware inside of the &lt;code&gt;computers&lt;/code&gt; collection. Let’s take a look at a sample payload index for the field &lt;code&gt;category&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Payload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;keyword:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;+------------+-------------+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;category&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;+------------+-------------+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;laptop&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;desktop&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;speakers&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;keyboard&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;+------------+-------------+&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When fields are properly indexed, the search engine roughly knows where it can start its journey. It can start looking up points that contain relevant metadata, and it doesn’t need to scan the entire dataset. This reduces the engine’s workload by a lot. As a result, query results are faster and the system can easily scale.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You may create as many payload indexes as you want, and we recommend you do so for each field that is frequently used. &lt;br&gt;
If your users are often filtering by &lt;strong&gt;laptop&lt;/strong&gt; when looking up a product &lt;strong&gt;category&lt;/strong&gt;, indexing all computer metadata will speed up retrieval and make the results more precise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Different types of payload indexes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Index Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/indexing/#full-text-index"&gt;Full-text Index&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Enables efficient text search in large datasets.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/indexing/#tenant-index"&gt;Tenant Index&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;For data isolation and retrieval efficiency in multi-tenant architectures.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/indexing/#principal-index"&gt;Principal Index&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Manages data based on primary entities like users or accounts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/indexing/#on-disk-payload-index"&gt;On-Disk Index&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Stores indexes on disk to manage large datasets without memory usage.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/documentation/concepts/indexing/#parameterized-index"&gt;Parameterized Index&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Allows for dynamic querying, where the index can adapt based on different parameters or conditions provided by the user. Useful for numeric data like prices or timestamps.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Indexing payloads in multitenant setups
&lt;/h2&gt;

&lt;p&gt;Some applications need to have data segregated, whereby different users need to see different data inside of the same program. When setting up storage for such a complex application, many users think they need multiple databases for segregated users.    &lt;/p&gt;

&lt;p&gt;We see this quite often. Users very frequently make the mistake of creating a separate collection for each tenant inside of the same cluster. This can quickly exhaust the cluster’s resources. Running vector search through too many collections can start using up too much RAM. You may start seeing out-of-memory (OOM) errors and degraded performance. &lt;/p&gt;

&lt;p&gt;To mitigate this, we offer extensive support for multitenant systems, so that you can build an entire global application in one single Qdrant collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT /collections/{collection_name}/index
{
   "field_name": "payload_field_name",
   "field_schema": {
       "type": "keyword",
       "is_tenant": true
   }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tenant index is another variant of the payload index. When creating or updating a collection, you can mark a metadata field as indexable. This time, the request will specify the field as a tenant. This means that you can mark various user types and customer id’s as &lt;code&gt;is_tenant&lt;/code&gt;: true. &lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways in filtering and indexing
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvghqy7yhnib2rs2znau.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvghqy7yhnib2rs2znau.png" alt="best-practices" width="800" height="139"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering with float-point (decimal) numbers
&lt;/h2&gt;

&lt;p&gt;If you filter by the float data type, your search precision may be limited and inaccurate. &lt;/p&gt;

&lt;p&gt;Float Datatype numbers have a decimal point and are 64 bits in size. Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11.99&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you filter for a specific float number, such as 11.99, you may get a different result, like 11.98 or 12.00. With decimals, numbers are rounded differently, so logically identical values may appear different. Unfortunately, searching for exact matches can be unreliable in this case.&lt;/p&gt;

&lt;p&gt;To avoid inaccuracies, use a different filtering method. We recommend that you try Range Based Filtering instead of exact matches. This method accounts for minor variations in data, and it boosts performance - especially with large datasets. &lt;/p&gt;

&lt;p&gt;Here is a sample JSON range filter for values greater than or equal to 11.99 and less than or equal to the same number. This will retrieve any values within the range of 11.99, including those with additional decimal places.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"gt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"gte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"lt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"lte"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;11.99&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Working with pagination in queries
&lt;/h2&gt;

&lt;p&gt;When you're implementing pagination in filtered queries, indexing becomes even more critical. When paginating results, you often need to exclude items you've already seen. This is typically managed by applying filters that specify which IDs should not be included in the next set of results. &lt;/p&gt;

&lt;p&gt;However, an interesting aspect of Qdrant's data model is that a single point can have multiple values for the same field, such as different color options for a product. This means that during filtering, an ID might appear multiple times if it matches on different values of the same field. &lt;/p&gt;

&lt;p&gt;Proper indexing ensures that these queries are efficient, preventing duplicate results and making pagination smoother.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Real-life use cases of filtering
&lt;/h2&gt;

&lt;p&gt;Filtering in a &lt;a href="https://qdrant.tech" rel="noopener noreferrer"&gt;vector database&lt;/a&gt; like Qdrant can significantly enhance search capabilities by enabling more precise and efficient retrieval of data. &lt;/p&gt;

&lt;p&gt;As a conclusion to this guide, let's look at some real-life use cases where filtering is crucial:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Vector Search&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Filtering&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/advanced-search/"&gt;E-Commerce Product Search&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Search for products by style or visual similarity&lt;/td&gt;
&lt;td&gt;Filter by price, color, brand, size, ratings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/recommendations/"&gt;Recommendation Systems&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Recommend similar content (e.g., movies, songs)&lt;/td&gt;
&lt;td&gt;Filter by release date, genre, etc. (e.g., movies after 2020)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/articles/geo-polygon-filter-gsoc/"&gt;Geospatial Search in Ride-Sharing&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Find similar drivers or delivery partners&lt;/td&gt;
&lt;td&gt;Filter by rating, distance radius, vehicle type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/data-analysis-anomaly-detection/"&gt;Fraud &amp;amp; Anomaly Detection&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Detect transactions similar to known fraud cases&lt;/td&gt;
&lt;td&gt;Filter by amount, time, location&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Before you go - all the code is in Qdrant's Dashboard
&lt;/h3&gt;

&lt;p&gt;The easiest way to reach that "Hello World" moment is to &lt;a href="https://dev.to/documentation/quickstart-cloud/"&gt;&lt;strong&gt;try filtering in a live cluster&lt;/strong&gt;&lt;/a&gt;. Our interactive tutorial will show you how to create a cluster, add data and try some filtering clauses. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>learning</category>
      <category>database</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>What is RAG (Retrieval-Augmented Generation)?</title>
      <dc:creator>Sabrina</dc:creator>
      <pubDate>Tue, 19 Mar 2024 16:47:57 +0000</pubDate>
      <link>https://dev.to/qdrant/what-is-rag-understanding-retrieval-augmented-generation-534n</link>
      <guid>https://dev.to/qdrant/what-is-rag-understanding-retrieval-augmented-generation-534n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Retrieval-augmented generation (RAG) integrates external information retrieval into the process of generating responses by Large Language Models (LLMs). It searches a database for information beyond its pre-trained knowledge base, significantly improving the accuracy and relevance of the generated responses.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Language models have exploded on the internet ever since ChatGPT came out, and rightfully so. They can write essays, code entire programs, and even make memes (though we’re still deciding on whether that's a good thing).&lt;/p&gt;

&lt;p&gt;But as brilliant as these chatbots become, they still have &lt;strong&gt;limitations&lt;/strong&gt; in tasks requiring external knowledge and factual information. &lt;/p&gt;

&lt;p&gt;Yes, it can describe the honeybee's waggle dance in excruciating detail. But they become far more valuable if they can generate insights from &lt;strong&gt;any data&lt;/strong&gt; that we provide, rather than just their &lt;em&gt;original training data.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Since retraining those large language models from scratch costs millions of dollars and takes months, we need better ways to give our existing LLMs access to our custom data.&lt;/p&gt;

&lt;p&gt;While you could be more creative with your prompts, it is only a short-term solution. LLMs can consider only a &lt;strong&gt;limited&lt;/strong&gt; amount of text in their responses, known as a &lt;a href="https://www.hopsworks.ai/dictionary/context-window-for-llms"&gt;context window&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Some models like GPT-3 can see up to around 12 pages of text (that’s 4,096 tokens of context). That’s not good enough for most knowledge bases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbo4w8jqvyqxduzq9fwi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbo4w8jqvyqxduzq9fwi5.png" alt="How a RAG works" width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows how a basic RAG system works. Before forwarding the question to the LLM, we have a layer that searches our knowledge base for the "relevant knowledge" to answer the user query. Specifically, in this case, the spending data from the last month. &lt;/p&gt;

&lt;p&gt;Our LLM can now generate a &lt;strong&gt;relevant non-hallucinated&lt;/strong&gt; response about our budget. &lt;/p&gt;

&lt;p&gt;As your data grows, you’ll need efficient ways to identify the most relevant information for your LLM's limited memory. This is where you’ll want a proper way to store and retrieve the specific data you’ll need for your query, without needing the LLM to remember it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vector databases&lt;/strong&gt; store information as &lt;strong&gt;vector embeddings&lt;/strong&gt;. This format supports efficient similarity searches to retrieve relevant data for your query. For example, Qdrant is specifically designed to perform fast, even in scenarios dealing with billions of vectors.&lt;/p&gt;

&lt;p&gt;This article will focus on RAG systems and architecture. If you’re interested in learning more about vector search, we recommend the following articles: &lt;a href="https://qdrant.tech/articles/what-is-a-vector-database/"&gt;What is a Vector Database?&lt;/a&gt; and &lt;a href="https://qdrant.tech/articles/what-are-embeddings/"&gt;What are Vector Embeddings?&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  RAG architecture
&lt;/h2&gt;

&lt;p&gt;At its core, a RAG architecture includes the &lt;strong&gt;retriever&lt;/strong&gt; and the &lt;strong&gt;generator&lt;/strong&gt;. Let's start by understanding what each of these components does.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Retriever
&lt;/h3&gt;

&lt;p&gt;When you ask a question to the retriever, it uses &lt;strong&gt;similarity search&lt;/strong&gt; to scan through a vast knowledge base of vector embeddings. It then pulls out the most &lt;strong&gt;relevant&lt;/strong&gt; vectors to help answer that query. There are a few different techniques it can use to know what’s relevant:&lt;/p&gt;

&lt;h3&gt;
  
  
  How indexing works in RAG retrievers
&lt;/h3&gt;

&lt;p&gt;The indexing process organizes the data into your vector database in a way that makes it easily searchable. This allows the RAG to access relevant information when responding to a query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w6dvfzo4s4dep9t8ryc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w6dvfzo4s4dep9t8ryc.png" alt="How indexing works" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown in the image above, here’s the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with a &lt;em&gt;loader&lt;/em&gt; that gathers &lt;em&gt;documents&lt;/em&gt; containing your data. These documents could be anything from articles and books to web pages and social media posts. &lt;/li&gt;
&lt;li&gt;Next, a &lt;em&gt;splitter&lt;/em&gt; divides the documents into smaller chunks, typically sentences or paragraphs. &lt;/li&gt;
&lt;li&gt;This is because RAG models work better with smaller pieces of text. In the diagram, these are &lt;em&gt;document snippets&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Each text chunk is then fed into an &lt;em&gt;embedding machine&lt;/em&gt;. This machine uses complex algorithms to convert the text into &lt;a href="https://qdrant.tech/articles/what-are-embeddings/"&gt;vector embeddings&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the generated vector embeddings are stored in a knowledge base of indexed information. This supports efficient retrieval of similar pieces of information when needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query vectorization
&lt;/h3&gt;

&lt;p&gt;Once you have vectorized your knowledge base you can do the same to the user query. When the model sees a new query, it uses the same preprocessing and embedding techniques. This ensures that the query vector is compatible with the document vectors in the index.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgqcvfupjx6pvtc9nttz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgqcvfupjx6pvtc9nttz.png" alt="How retrieval works" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Retrieval of relevant documents
&lt;/h3&gt;

&lt;p&gt;When the system needs to find the most relevant documents or passages to answer a query, it utilizes vector similarity techniques. &lt;strong&gt;Vector similarity&lt;/strong&gt; is a fundamental concept in machine learning and natural language processing (NLP) that quantifies the resemblance between vectors, which are mathematical representations of data points.&lt;/p&gt;

&lt;p&gt;The system can employ different vector similarity strategies depending on the type of vectors used to represent the data:&lt;/p&gt;

&lt;h4&gt;
  
  
  Sparse vector representations
&lt;/h4&gt;

&lt;p&gt;A sparse vector is characterized by a high dimensionality, with most of its elements being zero.&lt;/p&gt;

&lt;p&gt;The classic approach is &lt;strong&gt;keyword search&lt;/strong&gt;, which scans documents for the exact words or phrases in the query. The search creates sparse vector representations of documents by counting word occurrences and inversely weighting common words. Queries with rarer words get prioritized.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fez1mthlieogdyfv6lvlc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fez1mthlieogdyfv6lvlc.png" alt="Sparse Vectors explanation" width="800" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Tf%E2%80%93idf"&gt;TF-IDF&lt;/a&gt; (Term Frequency-Inverse Document Frequency) and &lt;a href="https://en.wikipedia.org/wiki/Okapi_BM25"&gt;BM25&lt;/a&gt; are two classic related algorithms. They're simple and computationally efficient. However, they can struggle with synonyms and don't always capture semantic similarities.&lt;/p&gt;

&lt;p&gt;If you’re interested in going deeper, refer to our article on &lt;a href="https://qdrant.tech/articles/sparse-vectors/"&gt;Sparse Vectors&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Dense vector embeddings
&lt;/h4&gt;

&lt;p&gt;This approach uses large language models like &lt;a href="https://en.wikipedia.org/wiki/BERT_(language_model)"&gt;BERT&lt;/a&gt; to encode the query and passages into dense vector embeddings. These models are compact numerical representations that capture semantic meaning. Vector databases like Qdrant store these embeddings, allowing retrieval based on &lt;strong&gt;semantic similarity&lt;/strong&gt; rather than just keywords using distance metrics like cosine similarity.&lt;/p&gt;

&lt;p&gt;This allows the retriever to match based on semantic understanding rather than just keywords. So if I ask about "compounds that cause BO," it can retrieve relevant info about "molecules that create body odor" even if those exact words weren't used. We explain more about it in our &lt;a href="https://qdrant.tech/articles/what-are-embeddings/"&gt;What are Vector Embeddings&lt;/a&gt; article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid search
&lt;/h3&gt;

&lt;p&gt;However, neither keyword search nor vector search are always perfect. Keyword search may miss relevant information expressed differently, while vector search can sometimes struggle with specificity or neglect important statistical word patterns. Hybrid methods aim to combine the strengths of different techniques.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws5e60ew6dawaobvf3v6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws5e60ew6dawaobvf3v6.png" alt="Hybrid search overview" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some common hybrid approaches include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using keyword search to get an initial set of candidate documents. Next, the documents are re-ranked/re-scored using semantic vector representations.&lt;/li&gt;
&lt;li&gt;Starting with semantic vectors to find generally topically relevant documents. Next, the documents are filtered/re-ranked e based on keyword matches or other metadata.&lt;/li&gt;
&lt;li&gt;Considering both semantic vector closeness and statistical keyword patterns/weights in a combined scoring model.&lt;/li&gt;
&lt;li&gt;Having multiple stages were different techniques. One example: start with an initial keyword retrieval, followed by semantic re-ranking, then a final re-ranking using even more complex models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you combine the powers of different search methods in a complementary way, you can provide higher quality, more comprehensive results. Check out our article on &lt;a href="https://qdrant.tech/articles/hybrid-search/"&gt;Hybrid Search&lt;/a&gt; if you’d like to learn more.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Generator
&lt;/h2&gt;

&lt;p&gt;With the top relevant passages retrieved, it's now the generator's job to produce a final answer by synthesizing and expressing that information in natural language. &lt;/p&gt;

&lt;p&gt;The LLM is typically a model like GPT, BART or T5, trained on massive datasets to understand and generate human-like text. It now takes not only the query (or question) as input but also the relevant documents or passages that the retriever identified as potentially containing the answer to generate its response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlq9rw4mw26gvf4qxl9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlq9rw4mw26gvf4qxl9r.png" alt="How a Generator works" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The retriever and generator don't operate in isolation. The image bellow shows how the output of the retrieval feeds the generator to produce the final generated response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fckvyszdo4cyklt09ts38.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fckvyszdo4cyklt09ts38.png" alt="The entire architecture of a RAG system" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where is RAG being used?
&lt;/h2&gt;

&lt;p&gt;Because of their more knowledgeable and contextual responses, we can find RAG models being applied in many areas today, especially those who need factual accuracy and knowledge depth. &lt;/p&gt;

&lt;h3&gt;
  
  
  Real-World Applications:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question answering:&lt;/strong&gt; This is perhaps the most prominent use case for RAG models. They power advanced question-answering systems that can retrieve relevant information from large knowledge bases and then generate fluent answers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Language generation:&lt;/strong&gt; RAG enables more factual and contextualized text generation for contextualized text summarization from multiple sources&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data-to-text generation:&lt;/strong&gt; By retrieving relevant structured data, RAG models can generate product/business intelligence reports from databases or describing insights from data visualizations and charts&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multimedia understanding:&lt;/strong&gt; RAG isn't limited to text - it can retrieve multimodal information like images, video, and audio to enhance understanding. Answering questions about images/videos by retrieving relevant textual context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating your first RAG chatbot with Langchain, Groq, and OpenAI
&lt;/h2&gt;

&lt;p&gt;Are you ready to create your own RAG chatbot from the ground up? We have a video explaining everything from the beginning. Daniel Romero’s will guide you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up your chatbot&lt;/li&gt;
&lt;li&gt;Preprocessing and organizing data for your chatbot's use&lt;/li&gt;
&lt;li&gt;Applying vector similarity search algorithms&lt;/li&gt;
&lt;li&gt;Enhancing the efficiency and response quality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After building your RAG chatbot, you'll be able to evaluate its performance against that of a chatbot powered solely by a Large Language Model (LLM).&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/O60-KuZZeQA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;Have a RAG project you want to bring to life? Join our &lt;a href="//discord.gg/qdrant"&gt;Discord community&lt;/a&gt; where we’re always sharing tips and answering questions on vector search and retrieval.&lt;/p&gt;

&lt;p&gt;Learn more about how to properly evaluate your RAG responses: &lt;a href="https://superlinked.com/vectorhub/evaluating-retrieval-augmented-generation-a-framework-for-assessment"&gt;Evaluating Retrieval Augmented Generation - a framework for assessment&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What are Vector Embeddings?</title>
      <dc:creator>Sabrina</dc:creator>
      <pubDate>Wed, 07 Feb 2024 17:56:15 +0000</pubDate>
      <link>https://dev.to/qdrant/what-are-vector-embeddings-24pd</link>
      <guid>https://dev.to/qdrant/what-are-vector-embeddings-24pd</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Embeddings&lt;/strong&gt; are numerical machine learning representations of the semantic of the input data. They capture the meaning of complex, high-dimensional data, like text, images, or audio, into vectors. Enabling algorithms to process and analyze the data more efficiently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Use Vector Embeddings?
&lt;/h2&gt;

&lt;p&gt;You know when you’re scrolling through your social media feeds and the content just feels incredibly tailored to you? There's the news you care about, followed by a perfect tutorial with your favorite tech stack, and then a meme that makes you laugh so hard you snort.&lt;/p&gt;

&lt;p&gt;Or what about how YouTube recommends videos you ended up loving. It’s by creators you've never even heard of and you didn’t even send YouTube a note about your ideal content lineup.&lt;/p&gt;

&lt;p&gt;This is the magic of embeddings.&lt;/p&gt;

&lt;p&gt;These are the result of &lt;strong&gt;deep learning models&lt;/strong&gt; analyzing the data of your interactions online. From your likes, shares, comments, searches, the kind of content you linger on, and even the content you decide to skip. It also allows the algorithm to predict future content that you are likely to appreciate.&lt;/p&gt;

&lt;p&gt;The same embeddings can be repurposed for search, ads, and other features, creating a highly personalized user experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3364e5wsuqj6kmkk076f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3364e5wsuqj6kmkk076f.png" alt="How embeddings are applied to perform recommendantions and other use cases" width="720" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They make &lt;a href="https://www.sciencedirect.com/topics/computer-science/high-dimensional-data" rel="noopener noreferrer"&gt;high-dimensional&lt;/a&gt; data more manageable. This reduces storage requirements, improves computational efficiency, and makes sense of a ton of &lt;strong&gt;unstructured&lt;/strong&gt; data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do embeddings work?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;nuances&lt;/strong&gt; of natural language or the hidden &lt;strong&gt;meaning&lt;/strong&gt; in large datasets of images, sounds, or user interactions are hard to fit into a table. Traditional relational databases can't efficiently query most types of data being currently used and produced, making the &lt;strong&gt;retrieval&lt;/strong&gt; of this information very limited.&lt;/p&gt;

&lt;p&gt;In the embeddings space, synonyms tend to appear in similar contexts and end up having similar embeddings. The space is a system smart enough to understand that "pretty" and "attractive" are playing for the same team. Without being explicitly told so. &lt;/p&gt;

&lt;p&gt;That’s the magic.&lt;/p&gt;

&lt;p&gt;At their core, vector embeddings are about semantics. They take the idea that "a word is known by the company it keeps" and apply it on a grand scale. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqszeqbs7qwm3p7jg4u4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqszeqbs7qwm3p7jg4u4h.png" alt="Example of how synonyms are placed closer together in the embeddings space" width="720" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This capability is crucial for creating search systems, recommendation engines, retrieval augmented generation (RAG) and any application that benefits from a deep understanding of content.&lt;/p&gt;

&lt;p&gt;Embeddings are created through neural networks. They capture complex relationships and semantics into &lt;a href="https://www1.se.cuhk.edu.hk/~seem5680/lecture/semantics-with-dense-vectors-2018.pdf" rel="noopener noreferrer"&gt;dense vectors&lt;/a&gt; which are more suitable for machine learning and data processing applications. They can then project these vectors into a proper &lt;strong&gt;high-dimensional&lt;/strong&gt; space, specifically, a &lt;a href="https://qdrant.tech/articles/what-is-a-vector-database/" rel="noopener noreferrer"&gt;Vector Database&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsy1gd0of5zlgxj68f7ta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsy1gd0of5zlgxj68f7ta.png" alt="The process for turning raw data into embeddings and placing them into the vector space" width="720" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The meaning of a data point is implicitly defined by its &lt;strong&gt;position&lt;/strong&gt; on the vector space. After the vectors are stored, we can use their spatial properties to perform &lt;a href="https://en.wikipedia.org/wiki/Nearest_neighbor_search#:~:text=Nearest%20neighbor%20search%20(NNS)%2C,the%20larger%20the%20function%20values." rel="noopener noreferrer"&gt;nearest neighbor searches&lt;/a&gt;. These searches retrieve semantically similar items based on how close they are in this space.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The quality of the vector representations drives the performance. The embedding model that works best for you depends on your use case.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Creating Vector Embeddings
&lt;/h2&gt;

&lt;p&gt;Embeddings translate the complexities of human language to a format that computers can understand. It uses neural networks to assign &lt;strong&gt;numerical values&lt;/strong&gt; to the input data, in a way that similar data has similar values.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevrb8i2gd9y4uclbfixc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevrb8i2gd9y4uclbfixc.png" alt="The process of using Neural Networks to create vector embeddings" width="720" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, if I want to make my computer understand the word 'right', I can assign a number like 1.3. So when my computer sees  1.3, it sees the word 'right’.&lt;/p&gt;

&lt;p&gt;Now I want to make my computer understand the context of the word ‘right’. I can use a two-dimensional vector, such as [1.3, 0.8], to represent 'right'. The first number 1.3 still identifies the word 'right', but the second number 0.8 specifies the context.&lt;/p&gt;

&lt;p&gt;We can introduce more dimensions to capture more nuances. For example, a third dimension could represent formality of the word, a fourth could indicate its emotional connotation (positive, neutral, negative), and so on. &lt;/p&gt;

&lt;p&gt;The evolution of this concept led to the development of embedding models like &lt;a href="https://en.wikipedia.org/wiki/Word2vec" rel="noopener noreferrer"&gt;Word2Vec&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/GloVe" rel="noopener noreferrer"&gt;GloVe&lt;/a&gt;. They learn to understand the context in which words appear to generate high-dimensional vectors for each word, capturing far more complex properties. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbariijzbgj9madaseze7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbariijzbgj9madaseze7.png" alt="How Word2Vec model creates the embeddings for a word" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, these models still have limitations. They generate a single vector per word, based on its usage across texts. This means all the nuances of the word "right" are blended into one vector representation. That is not enough information for computers to fully understand the context.&lt;/p&gt;

&lt;p&gt;So, how do we help computers grasp the nuances of language in different contexts? In other words, how do we differentiate between: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"your answer is right" &lt;/li&gt;
&lt;li&gt;"turn right at the corner"&lt;/li&gt;
&lt;li&gt;"everyone has the right to freedom of speech"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these sentences use the word 'right', with different meanings.&lt;/p&gt;

&lt;p&gt;More advanced models like &lt;a href="https://en.wikipedia.org/wiki/BERT_(language_model)" rel="noopener noreferrer"&gt;BERT&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Generative_pre-trained_transformer" rel="noopener noreferrer"&gt;GPT&lt;/a&gt; use deep learning models based on the &lt;a href="https://arxiv.org/abs/1706.03762" rel="noopener noreferrer"&gt;transformer architecture&lt;/a&gt;, which helps computers consider the full context of a word. These models pay attention to the entire context. The model understands the specific use of a word in its &lt;strong&gt;surroundings&lt;/strong&gt;, and then creates different embeddings for each.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq5cdug5numi5w2y1l4ii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq5cdug5numi5w2y1l4ii.png" alt="How the BERT model creates the embeddings for a word" width="720" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But how does this process of understanding and interpreting work in practice? Think of the term: "biophilic design", for example. To generate its embedding, the transformer architecture can use the following  contexts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Biophilic design incorporates natural elements into architectural planning."&lt;/li&gt;
&lt;li&gt;"Offices with biophilic design elements report higher employee well-being."&lt;/li&gt;
&lt;li&gt;"...plant life, natural light, and water features are key aspects of biophilic design."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then it compares contexts to known architectural and design principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Sustainable designs prioritize environmental harmony."&lt;/li&gt;
&lt;li&gt;"Ergonomic spaces enhance user comfort and health."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model creates a vector embedding for "biophilic design" that encapsulates the concept of integrating natural elements into man-made environments. Augmented with attributes that highlight the correlation between this integration and its positive impact on health, well-being, and environmental sustainability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integration with Embedding APIs
&lt;/h3&gt;

&lt;p&gt;Selecting the right embedding model for your use case is crucial to your application performance. Qdrant makes it easier by offering seamless integration with the best selection of embedding APIs, including &lt;a href="https://qdrant.tech/documentation/embeddings/cohere/" rel="noopener noreferrer"&gt;Cohere&lt;/a&gt;, &lt;a href="https://qdrant.tech/documentation/embeddings/gemini/" rel="noopener noreferrer"&gt;Gemini&lt;/a&gt;, &lt;a href="https://qdrant.tech/documentation/embeddings/jina-embeddings/" rel="noopener noreferrer"&gt;Jina Embeddings&lt;/a&gt;, &lt;a href="https://qdrant.tech/documentation/embeddings/openai/" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;, &lt;a href="https://qdrant.tech/documentation/embeddings/aleph-alpha/" rel="noopener noreferrer"&gt;Aleph Alpha&lt;/a&gt;, &lt;a href="https://github.com/qdrant/fastembed" rel="noopener noreferrer"&gt;Fastembed&lt;/a&gt;, and &lt;a href="https://qdrant.tech/documentation/embeddings/bedrock/" rel="noopener noreferrer"&gt;AWS Bedrock&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you’re looking for NLP and rapid prototyping, including language translation, question-answering, and text generation, OpenAI is a great choice. Gemini is ideal for image search, duplicate detection, and clustering tasks. &lt;/p&gt;

&lt;p&gt;Fastembed, which we’ll use on the example below, is designed for efficiency and speed, great for applications needing low-latency responses, such as autocomplete and instant content recommendations. &lt;/p&gt;

&lt;p&gt;I plan to go deeper into selecting the best model based on performance, cost, integration ease, and scalability in a future post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Neural Search Service with Fastembed
&lt;/h2&gt;

&lt;p&gt;Now that you’re familiar with the core concepts around vector embeddings, how about start building your own &lt;a href="https://qdrant.tech/documentation/tutorials/neural-search-fastembed/" rel="noopener noreferrer"&gt;Neural Search Service&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Tutorial guides you through a practical application of how to use Qdrant for document management based on descriptions of companies from &lt;a href="https://www.startups-list.com/" rel="noopener noreferrer"&gt;startups-list.com&lt;/a&gt;. From embedding data, integrating it with Qdrant's vector database, constructing a search API, and finally deploying your solution with FastAPI.&lt;/p&gt;

&lt;p&gt;Check out what the final version of this project looks like on the &lt;a href="https://qdrant.to/semantic-search-demo" rel="noopener noreferrer"&gt;live online demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let us know what you’re building with embeddings! Join our &lt;a href="https://discord.gg/qdrant-907569970500743200" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; community and share your projects!&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>opensource</category>
      <category>vectordatabase</category>
    </item>
    <item>
      <title>What is a Vector Database?</title>
      <dc:creator>Sabrina</dc:creator>
      <pubDate>Thu, 25 Jan 2024 21:29:58 +0000</pubDate>
      <link>https://dev.to/qdrant/what-is-a-vector-database-2h0b</link>
      <guid>https://dev.to/qdrant/what-is-a-vector-database-2h0b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A Vector Database is a specialized database system designed for efficiently indexing, querying, and retrieving high-dimensional vector data. Those systems enable advanced data analysis and similarity-search operations that extend well beyond the traditional, structured query approach of conventional databases.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why use a Vector Database?
&lt;/h2&gt;

&lt;p&gt;The data flood is real. &lt;/p&gt;

&lt;p&gt;In 2024, we're drowning in unstructured data like images, text, and audio, that don’t fit into neatly organized tables. Still, we need a way to easily tap into the value within this chaos of almost 330 million terabytes of data being created each day.&lt;/p&gt;

&lt;p&gt;Traditional databases, even with extensions that provide some vector handling capabilities, struggle with the complexities and demands of high-dimensional vector data. &lt;/p&gt;

&lt;p&gt;Handling of vector data is extremely resource-intensive. A traditional vector is around 6Kb. You can see how scaling to millions of vectors can demand substantial system memory and computational resources. Which is at least very challenging for traditional &lt;a href="https://www.ibm.com/topics/oltp" rel="noopener noreferrer"&gt;OLTP&lt;/a&gt; and &lt;a href="https://www.ibm.com/topics/olap" rel="noopener noreferrer"&gt;OLAP&lt;/a&gt; databases to manage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4vg4uxgax6dkrzipvvh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4vg4uxgax6dkrzipvvh.jpg" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vector databases allow you to understand the &lt;strong&gt;context&lt;/strong&gt; or &lt;strong&gt;conceptual similarity&lt;/strong&gt; of unstructured data by representing them as &lt;strong&gt;vectors&lt;/strong&gt;, enabling advanced analysis and retrieval based on data similarity.&lt;/p&gt;

&lt;p&gt;For example, in recommendation systems, vector databases can analyze user behavior and item characteristics to suggest products or content with a high degree of personal relevance. &lt;/p&gt;

&lt;p&gt;In search engines and research databases, they enhance the user experience by providing results that are &lt;strong&gt;semantically&lt;/strong&gt; similar to the query, rather than relying solely on the exact words typed into the search bar.&lt;/p&gt;

&lt;p&gt;If you’re new to the vector search space, this article explains the key concepts and relationships that you need to know.&lt;/p&gt;

&lt;p&gt;So let's get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Vector Data?
&lt;/h2&gt;

&lt;p&gt;To understand vector databases, let's begin by defining what is a 'vector' or 'vector data'. &lt;/p&gt;

&lt;p&gt;Vectors are a &lt;strong&gt;numerical representation&lt;/strong&gt; of some type of complex information. &lt;/p&gt;

&lt;p&gt;To represent textual data, for example, it will encapsulate the nuances of language, such as semantics and context. &lt;/p&gt;

&lt;p&gt;With an image, the vector data encapsulates aspects like color, texture, and shape. The &lt;strong&gt;dimensions&lt;/strong&gt; relate to the complexity and the amount of information each image contains. &lt;/p&gt;

&lt;p&gt;Each pixel in an image can be seen as one dimension, as it holds data (like color intensity values for red, green, and blue channels in a color image). So even a small image with thousands of pixels translates to thousands of dimensions.&lt;/p&gt;

&lt;p&gt;So from now on, when we talk about high-dimensional data, we mean that the data contains a large number of data points (pixels, features, semantics, syntax). &lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;creation&lt;/strong&gt; of vector data (so we can store this high-dimensional data on our vector database) is primarily done through &lt;strong&gt;embeddings&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fj4euxeao2896k4jzwz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fj4euxeao2896k4jzwz.jpg" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How do Embeddings Work?
&lt;/h3&gt;

&lt;p&gt;Embeddings translate this high-dimensional data into a more manageable, &lt;strong&gt;lower-dimensional&lt;/strong&gt; vector form that's more suitable for machine learning and data processing applications, typically through &lt;strong&gt;neural network models&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In creating dimensions for text, for example, the process involves analyzing the text to capture its linguistic elements. &lt;/p&gt;

&lt;p&gt;Transformer-based neural networks like &lt;strong&gt;BERT&lt;/strong&gt; (Bidirectional Encoder Representations from Transformers) and &lt;strong&gt;GPT&lt;/strong&gt; (Generative Pre-trained Transformer), are widely used for creating text embeddings. &lt;/p&gt;

&lt;p&gt;Each layer extracts different levels of features, such as context, semantics, and syntax.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1uw2homrkxwg7xs2i5r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1uw2homrkxwg7xs2i5r.jpg" width="800" height="741"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final layers of the network condense this information into a vector that is a compact, lower-dimensional representation of the image but still retains the essential information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Functionalities of Vector Databases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Indexing?
&lt;/h3&gt;

&lt;p&gt;Have you ever tried to find a specific face in a massive crowd photo? Well, vector databases face a similar challenge when dealing with tons of high-dimensional vectors. &lt;/p&gt;

&lt;p&gt;Now, imagine dividing the crowd into smaller groups based on hair color, then eye color, then clothing style. Each layer gets you closer to who you’re looking for. Vector databases use similar &lt;strong&gt;multi-layered&lt;/strong&gt; structures called indexes to organize vectors based on their "likeness." &lt;/p&gt;

&lt;p&gt;This way, finding similar images becomes a quick hop across related groups, instead of scanning every picture one by one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpfvngcefmfcm5ckqdugl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpfvngcefmfcm5ckqdugl.jpg" width="800" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Different indexing methods exist, each with its strengths. &lt;a href="https://qdrant.tech/articles/filtrable-hnsw/" rel="noopener noreferrer"&gt;HNSW&lt;/a&gt; balances speed and accuracy like a well-connected network of shortcuts in the crowd. Others, like IVF or Product Quantization, focus on specific tasks or memory efficiency.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Binary Quantization?
&lt;/h4&gt;

&lt;p&gt;Quantization is a technique used for reducing the total size of the database. It works by compressing vectors into a more compact representation at the cost of accuracy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qdrant.tech/articles/binary-quantization/" rel="noopener noreferrer"&gt;Binary Quantization&lt;/a&gt; is a fast indexing and data compression method used by Qdrant. It supports vector comparisons, which can dramatically speed up query processing times (up to 40x faster!).&lt;/p&gt;

&lt;p&gt;Think of each data point as a ruler. Binary quantization splits this ruler in half at a certain point, marking everything above as "1" and everything below as "0". This &lt;a href="https://arc.net/l/quote/uezrjlae" rel="noopener noreferrer"&gt;binarization&lt;/a&gt; process results in a string of bits, representing the original vector.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bnwtvxu5aftptcc1zct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bnwtvxu5aftptcc1zct.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This "quantized" code is much smaller and easier to compare. Especially for OpenAI embeddings, this type of quantization has proven to achieve a massive performance improvement at a lower cost of accuracy.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Similarity Search?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://qdrant.tech/documentation/concepts/search/" rel="noopener noreferrer"&gt;Similarity search&lt;/a&gt; allows you to search not by keywords but by meaning. This way you can do searches such as similar songs that evoke the same mood, finding images that match your artistic vision, or even exploring emotional patterns in text.&lt;/p&gt;

&lt;p&gt;The way it works is, when the user queries the database, this query is also converted into a vector (the query vector). The &lt;a href="https://qdrant.tech/documentation/overview/vector-search/" rel="noopener noreferrer"&gt;vector search&lt;/a&gt; starts at the top layer of the HNSW index, where the algorithm quickly identifies the area of the graph likely to contain vectors closest to the query vector. The algorithm compares your query vector to all the others, using metrics like "distance" or "similarity" to gauge how close they are.&lt;/p&gt;

&lt;p&gt;The search then moves down progressively narrowing down to more closely related vectors. The goal is to narrow down the dataset to the most relevant items. The image below illustrates this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvrwbjbdo9yfc27wm2yti.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvrwbjbdo9yfc27wm2yti.jpg" width="800" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the closest vectors are identified at the bottom layer, these points translate back to actual data, like images or music, representing your search results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;Vector databases often deal with datasets that comprise billions of high-dimensional vectors. This data isn't just large in volume but also complex in nature, requiring more computing power and memory to process. Scalable systems can handle this increased complexity without performance degradation. This is achieved through a combination of a &lt;strong&gt;distributed architecture&lt;/strong&gt;, &lt;strong&gt;dynamic resource allocation&lt;/strong&gt;, &lt;strong&gt;data partitioning&lt;/strong&gt;, &lt;strong&gt;load balancing&lt;/strong&gt;, and &lt;strong&gt;optimization techniques&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Systems like Qdrant, exemplify scalability in vector databases. It leverages Rust's efficiency in &lt;strong&gt;memory management&lt;/strong&gt; and &lt;strong&gt;performance&lt;/strong&gt;, allowing handling of large-scale data with optimized resource usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Efficient Query Processing
&lt;/h3&gt;

&lt;p&gt;The key to efficient query processing in these databases is linked to their &lt;strong&gt;indexing methods&lt;/strong&gt;, which enable quick navigation through complex data structures. By mapping and accessing the high-dimensional vector space, HNSW and similar indexing techniques significantly reduce the time needed to locate and retrieve relevant data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8sy92b0uv6gr25o33mpt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8sy92b0uv6gr25o33mpt.jpg" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other techniques like &lt;strong&gt;handling computational load&lt;/strong&gt; and &lt;strong&gt;parallel processing&lt;/strong&gt; are used for performance, especially when managing multiple simultaneous queries. Complementing them, &lt;strong&gt;strategic caching&lt;/strong&gt; is also employed to store frequently accessed data, facilitating a quicker retrieval for subsequent queries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Metadata and Filters
&lt;/h3&gt;

&lt;p&gt;Filters use metadata to refine search queries within the database. For example, in a database containing text documents, a user might want to search for documents not only based on textual similarity but also filter the results by publication date or author.&lt;/p&gt;

&lt;p&gt;When a query is made, the system can use &lt;strong&gt;both&lt;/strong&gt; the vector data and the metadata to process the query. In other words, the database doesn’t just look for the closest vectors. It also considers the additional criteria set by the metadata filters, creating a more customizable search experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0e9wvku07xtnsbwen3z8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0e9wvku07xtnsbwen3z8.jpg" width="800" height="712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Security and Access Control
&lt;/h3&gt;

&lt;p&gt;Vector databases often store sensitive information. This could include personal data in customer databases, confidential images, or proprietary text documents. Ensuring data security means protecting this information from unauthorized access, breaches, and other forms of cyber threats.&lt;/p&gt;

&lt;p&gt;At Qdrant, this includes mechanisms such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User authentication&lt;/li&gt;
&lt;li&gt;Role-based access control&lt;/li&gt;
&lt;li&gt;Attribute-based access control&lt;/li&gt;
&lt;li&gt;Encryption for data at rest and in transit&lt;/li&gt;
&lt;li&gt;Keeping audit trails&lt;/li&gt;
&lt;li&gt;Advanced database monitoring and anomaly detection&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture of a Vector Database
&lt;/h2&gt;

&lt;p&gt;A vector database is made of multiple different entities and relations. Here's a high-level overview of Qdrant's terminologies and how they fit into the larger picture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3w9wo86kw1dn33imnwz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3w9wo86kw1dn33imnwz.jpg" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collections&lt;/strong&gt;: &lt;a href="https://qdrant.tech/documentation/concepts/collections/" rel="noopener noreferrer"&gt;Collections&lt;/a&gt; are a named set of data points, where each point is a vector with an associated payload. All vectors within a collection must have the same dimensionality and be comparable using a single metric.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distance Metrics&lt;/strong&gt;: These metrics are used to measure the similarity between vectors. The choice of distance metric is made when creating a collection. It depends on the nature of the vectors and how they were generated, considering the neural network used for the encoding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Points&lt;/strong&gt;: Each &lt;a href="https://qdrant.tech/documentation/concepts/points/" rel="noopener noreferrer"&gt;point&lt;/a&gt; consists of a &lt;strong&gt;vector&lt;/strong&gt; and can also include an optional &lt;strong&gt;identifier&lt;/strong&gt; (ID) and &lt;strong&gt;&lt;a href="https://qdrant.tech/documentation/concepts/payload/" rel="noopener noreferrer"&gt;payload&lt;/a&gt;&lt;/strong&gt;. The vector represents the high-dimensional data and the payload carries metadata information in a JSON format, giving the data point more context or attributes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Storage Options&lt;/strong&gt;: There are two primary storage options. The in-memory storage option keeps all vectors in RAM, which allows for the highest speed in data access since disk access is only required for persistence. &lt;/p&gt;

&lt;p&gt;Alternatively, the Memmap storage option creates a virtual address space linked with the file on disk, giving a balance between memory usage and access speed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clients&lt;/strong&gt;: Qdrant supports various programming languages for client interaction, such as Python, Go, Rust, and Typescript. This way developers can connect to and interact with Qdrant using the programming language they prefer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vector Database Use Cases
&lt;/h2&gt;

&lt;p&gt;If we had to summarize the use cases for vector databases into a single word, it would be "match". They are great at finding non-obvious ways to correspond or “match” data with a given query. Whether it's through similarity in images, text, user preferences, or patterns in data.&lt;/p&gt;

&lt;p&gt;Here are some examples of how to take advantage of using vector databases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personalized recommendation systems&lt;/strong&gt; to analyze and interpret complex user data, such as preferences, behaviors, and interactions. For example, on Spotify, if a user frequently listens to the same song or skips it, the recommendation engine takes note of this to personalize future suggestions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantic search&lt;/strong&gt; allows for systems to be able to capture the deeper semantic meaning of words and text. In modern search engines, if someone searches for "tips for planting in spring," it tries to understand the intent and contextual meaning behind the query. It doesn’t try just matching the words themselves. Here’s an example of a &lt;a href="https://demo.qdrant.tech/" rel="noopener noreferrer"&gt;vector search engine for Startups&lt;/a&gt; made with Qdrant:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruq5ldq7y58awlsby4ti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruq5ldq7y58awlsby4ti.png" width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many other use cases like for &lt;strong&gt;fraud detection and anomaly analysis&lt;/strong&gt; used in sectors like finance and cybersecurity, to detect anomalies and potential fraud. And &lt;strong&gt;Content-Based Image Retrieval (CBIR)&lt;/strong&gt; for images by comparing vector representations rather than metadata or tags. &lt;/p&gt;

&lt;p&gt;Those are just a few examples. The ability of vector databases to “match” data with queries makes them essential for multiple types of applications. Here are some more &lt;a href="https://qdrant.tech/use-cases/" rel="noopener noreferrer"&gt;use case examples&lt;/a&gt; you can take a look at.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting Your First Vector Database Project
&lt;/h2&gt;

&lt;p&gt;Now that you're familiar with the core concepts around vector databases, it’s time to get our hands dirty. &lt;a href="https://qdrant.tech/documentation/tutorials/search-beginners/" rel="noopener noreferrer"&gt;Start by building your own semantic search engine&lt;/a&gt; for science fiction books in just about 5 minutes with the help of Qdrant. You can also watch our &lt;a href="https://www.youtube.com/watch?v=AASiqmtKo54" rel="noopener noreferrer"&gt;video tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Feeling ready to dive into a more complex project? Take the next step and get started building an actual &lt;a href="https://qdrant.tech/documentation/tutorials/neural-search/" rel="noopener noreferrer"&gt;Neural Search Service with a complete API and a dataset&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let’s get into action!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>database</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Distributed Systems Like You're 5</title>
      <dc:creator>Sabrina</dc:creator>
      <pubDate>Thu, 30 Mar 2023 17:25:08 +0000</pubDate>
      <link>https://dev.to/sabrinaesaquino/explain-distributed-systems-like-im-5-51o6</link>
      <guid>https://dev.to/sabrinaesaquino/explain-distributed-systems-like-im-5-51o6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;TL;DR&lt;/em&gt;&lt;br&gt;
Let's break down distributed systems! In this blog post, I'll explore how a group of computers works together as a team to handle &lt;strong&gt;big tasks&lt;/strong&gt; and see how these systems are essential for solving real-world problems, optimizing databases and computing, and playing a major role in MLOps. I'll also be hosting a &lt;a href="https://twitter.com/i/spaces/1LyxBqRwLYWJN?s=20" rel="noopener noreferrer"&gt;Twitter Space&lt;/a&gt; tomorrow, where four distributed systems experts and I will dive deeper into building and maintaining distributed systems, addressing challenges, and sharing some best practices.d&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What are distributed systems?
&lt;/h2&gt;

&lt;p&gt;Imagine you're building a huge Minecraft castle, and you have to gather resources, craft items, and construct the entire structure on your own. It would be &lt;strong&gt;overwhelming&lt;/strong&gt; and &lt;strong&gt;time-consuming&lt;/strong&gt; to do everything by yourself. So, you invite your friends to join your server and help you. Each of you takes responsibility for gathering specific resources, crafting particular items, and constructing parts of the castle, making the whole process much faster and more enjoyable. That's what distributed systems are like – &lt;strong&gt;they take a big, complex task and break it down into smaller, manageable parts that can be done by different computers working together&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the world of computing, there are lots of tasks that are just too big for one computer to handle, and just like the Minecraft castle, these tasks need the help of many computers to get the job done quickly and efficiently. These computers work together as a team to complete the task by dividing it into &lt;strong&gt;smaller pieces&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvrwsgpooxihglpu0pj7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvrwsgpooxihglpu0pj7.jpg" alt="Huge minecraft building" width="602" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How do they work?
&lt;/h2&gt;

&lt;p&gt;Have you ever played a game of "Telephone"? It's a bit like that. Each computer passes along a message to the next one. They use "special languages", called protocols, to communicate with each other and share information, making sure that every computer has the information of what's going on and what part of the task they need to work on.&lt;/p&gt;

&lt;p&gt;To make sure the computers can communicate well and maintain consistency across the system, distributed systems use various algorithms and protocols. Consensus algorithms like Paxos and Raft help nodes agree on the state of the system, while data replication techniques like sharding and partitioning distribute data across computers for better fault tolerance, which means they can keep working even when something goes wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1srcvqq0ezgv180p6yl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1srcvqq0ezgv180p6yl.png" alt="fonte: https://www.atlassian.com/microservices/microservices-architecture/distributed-architecture" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where is it?
&lt;/h2&gt;

&lt;p&gt;Distributed systems are &lt;strong&gt;widely&lt;/strong&gt; used in real-world applications by some of the most popular tech companies. For instance, &lt;strong&gt;Google&lt;/strong&gt; uses distributed systems in its search engine infrastructure to handle billions of queries and return results quickly. Also, &lt;strong&gt;Netflix&lt;/strong&gt; relies on distributed systems to manage and deliver its massive library of movies and TV shows to millions of users around the globe. We can also mention &lt;em&gt;AWS&lt;/em&gt; and &lt;em&gt;Microsoft Azure&lt;/em&gt;, which provide cloud computing platforms built on distributed systems that enable businesses to scale their applications and services efficiently.&lt;/p&gt;

&lt;p&gt;If you're interested in getting started with distributed systems, there are plenty of resources available to help. You can begin by exploring online courses and tutorials covering the basics of distributed computing and parallel processing. It's also a great idea to experiment with some of the popular tools and technologies, like Apache Kafka, Apache Spark, and Dask. Working hands-on with these tools will give you a deeper understanding of how distributed systems work in practice and build the skills needed to work with them effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's talk about it!
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Looking for a live discussion about it with top industry experts to answer all your questions? Well, this is your lucky day&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I'm excited to invite you to our upcoming Twitter Spaces event, where we'll dive even deeper into distributed systems. We have an outstanding panel of experts who will share their knowledge and insights about distributed systems, answering all your questions and helping you easily learn this complex topic.&lt;/p&gt;

&lt;p&gt;The Spaces will happen tomorrow (Friday, March 31st) at 12 pm EST.&lt;/p&gt;

&lt;p&gt;Mark on your calendars and access the event through this link:&lt;br&gt;
&lt;a href="https://twitter.com/i/spaces/1LyxBqRwLYWJN?s=20" rel="noopener noreferrer"&gt;https://twitter.com/i/spaces/1LyxBqRwLYWJN?s=20&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw6p1wy1uw0ytv6cghsmt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw6p1wy1uw0ytv6cghsmt.jpg" alt="Twitter Spaces announcement" width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;
Set your reminders!&lt;/p&gt;

&lt;p&gt;Won't be able to attend live but would still like to watch? The recorded Spaces will be available on the same link.&lt;/p&gt;

</description>
      <category>spark</category>
      <category>programming</category>
      <category>beginners</category>
      <category>devops</category>
    </item>
    <item>
      <title>Como Consegui uma Carreira em DevRel Ainda na Faculdade</title>
      <dc:creator>Sabrina</dc:creator>
      <pubDate>Tue, 21 Feb 2023 17:43:43 +0000</pubDate>
      <link>https://dev.to/devrelbr/como-consegui-uma-carreira-em-devrel-ainda-na-faculdade-anc</link>
      <guid>https://dev.to/devrelbr/como-consegui-uma-carreira-em-devrel-ainda-na-faculdade-anc</guid>
      <description>&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Intro&lt;/li&gt;
&lt;li&gt;Fazendo Umas Piadinhas&lt;/li&gt;
&lt;li&gt;O PODER do Networking&lt;/li&gt;
&lt;li&gt;Levando um Hobby a Sério&lt;/li&gt;
&lt;li&gt;MUITA Coisa pra Aprender&lt;/li&gt;
&lt;li&gt;Resumindo: Como Começar uma Comunidade&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;TL;DR&lt;/em&gt;&lt;br&gt;
Nesse blog vou compartilhar a minha história &lt;strong&gt;"acidental"&lt;/strong&gt; como criadora de conteúdo, que me levou a conhecer pessoas incríveis e a oportunidade de trabalhar na área de DevRel enquanto ainda estou na faculdade. Vou falar sobre o que aprendi até agora, desde os meus primeiros tweets até a construção de uma &lt;strong&gt;carreira internacional&lt;/strong&gt;. Apanhei bastante pelo caminho, e essas são as maiores lições e dicas que tenho para quem gostaria de seguir um caminho parecido.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Intro &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Sem ter muito o que fazer durante a pandemia do Covid, decidi entrar em uma antiga conta minha do Twitter, que eu nunca realmente usei e devia ter um pouco mais de 5 followers na época. Comecei a &lt;strong&gt;seguir muitos tópicos e contas que eu achava interessante&lt;/strong&gt;, e alguns deles eram relacionados com Ciência da Computação.&lt;/p&gt;

&lt;p&gt;Nessa época eu já programava ocasionalmente na faculdade, e já tinha tido contato com programação pelo programa &lt;a href="https://pll.harvard.edu/course/cs50-introduction-computer-science?delta=0" rel="noopener noreferrer"&gt;CS50 de Harvard&lt;/a&gt; &lt;strong&gt;(essencial para quem está começando)&lt;/strong&gt; no meu ensino médio, que fiz técnico em informática, e alguns projetos soltos por aí. Mas nada muito &lt;strong&gt;uaaau&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Eventualmente me deparei com uma &lt;strong&gt;hashtag&lt;/strong&gt; que me chamou muita atenção, o &lt;a href="https://www.100daysofcode.com/" rel="noopener noreferrer"&gt;#100DaysOfCode&lt;/a&gt;. Que consiste basicamente da galera codando por 100 dias seguidos, &lt;strong&gt;no mínimo 1 hora por dia&lt;/strong&gt;, e &lt;strong&gt;tweetando&lt;/strong&gt; sobre o que aprendeu naquele dia. &lt;/p&gt;

&lt;p&gt;Decidi começar a aprender um pouco de &lt;strong&gt;front-end&lt;/strong&gt;, já que tinha muito conteúdo da galera ajudando a começar e era o tópico mais falado no tech twitter naquela época. Isso literalmente eu &lt;strong&gt;sem seguidores&lt;/strong&gt;, tá? Estava fazendo apenas pra me forçar a codar consistentemente e &lt;strong&gt;"bater o ponto"&lt;/strong&gt;, nem que fosse uma horinha só.&lt;/p&gt;

&lt;p&gt;Por isso, os tweets que eu fazia com a hashtag não tinha o intuito de ser muito informativo ou tentando ensinar algo. Geralmente era apenas um pensamento engraçado ou uma observação interessante de algo que eu aprendi.&lt;/p&gt;

&lt;p&gt;Por causa do alcance dessa hashtag na época, feita justamente com o intuito de dar visibilidade para novos devs e &lt;strong&gt;se ajudar como comunidade&lt;/strong&gt;, esses tweets começaram a ganhar uns likes. Lembro que no primeiro post já tive um engajamento e fiquei muito animada porque minha conta era realmente bem &lt;strong&gt;isolada&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjn1q2hbqkihxn94c6ei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjn1q2hbqkihxn94c6ei.png" alt="tweet Day1 #100DaysOfCode" width="533" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fui acumulando seguidores um pouquinho todo dia, e os tweets começaram a ganhar cada vez mais alcance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv2hfsu529qwiwjpon2d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv2hfsu529qwiwjpon2d.png" alt="tweet Day43 #100DaysOfCode" width="533" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7rjmv3uxgte5j3k80q50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7rjmv3uxgte5j3k80q50.png" alt="tweet Day54 #100DaysOfCode" width="536" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nessa época eu interagia &lt;strong&gt;muuito&lt;/strong&gt; com a galera através de DMs e comentários, formei amigos que converso até hoje, e conheci pessoas que são literalmente &lt;strong&gt;lendas&lt;/strong&gt; do tech twitter, como o legendário &lt;a href="https://twitter.com/TheJackForge" rel="noopener noreferrer"&gt;Jack Forge&lt;/a&gt;, que me ajudaram muito. Todo mundo era muito legal e aquilo tudo era muito &lt;strong&gt;novo&lt;/strong&gt; e &lt;strong&gt;interessante&lt;/strong&gt; para mim.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgaspzqvhy5p390qkyqwu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgaspzqvhy5p390qkyqwu.png" alt="Quote tweet from Jack Forge" width="536" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Fazendo Umas Piadinhas &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Muitas pessoas começaram a me seguir por se identificar com tipo de conteúdo mais sarcástico, que eu também gostava de fazer. E sem querer fui formando meu &lt;strong&gt;nicho&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Conseguir &lt;strong&gt;criar e identificar o seu nicho&lt;/strong&gt; é uma das etapas mais importantes na criação de conteúdo, e é o que vai fazer a diferença entre você crescer rápido ou devagar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29obd6cmurhjxjk6bxgu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29obd6cmurhjxjk6bxgu.png" alt="tweet @sabrinaesaquino " width="540" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com o tempo eu entendi que, quando postava conteúdo para esse nicho, o engajamento tomava maiores proporções. Isso acontece porque minha audiência são pessoas que &lt;strong&gt;gostam&lt;/strong&gt; desses tweets e &lt;strong&gt;já relacionaram&lt;/strong&gt; eles com a minha conta, então elas são muito mais prováveis de curtir ou retuitar esse conteúdo.&lt;/p&gt;

&lt;p&gt;Ser receptivo nos comentários faz as pessoas interagirem com você com mais frequência. Aqui estão alguns dos comentários desse mesmo post que acabei de mostrar:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxm96ddrjkgcm4armx3xo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxm96ddrjkgcm4armx3xo.png" alt="tweet comments" width="541" height="854"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comentários também são uma das ferramentas mais poderosas para aumentar o seu alcance. A maior parte de como as pessoas vão te ver e decidir se gostam ou não de você é observando como você &lt;strong&gt;interage&lt;/strong&gt; com outros usuários ou seguidores nos comentários.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl52up3bhwqtbn95juqz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl52up3bhwqtbn95juqz.png" alt="tweet comments" width="541" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Todo o processo de entender como criação de conteúdo funciona e como utilizar o algoritmo ao seu favor são pontos cruciais se você planeja criar uma audiência para o seu conteúdo.&lt;/p&gt;

&lt;p&gt;Nesse post, eu ganhei muito alcance apenas respondendo comentários, e contas com poucos seguidores também ganharam bastante visibilidade com um simples reply.&lt;/p&gt;

&lt;h2&gt;
  
  
  O PODER do Networking &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Quando eu estava começando, interagir com a comunidade foi crucial para o meu crescimento. Além disso te permitir conhecer pessoas incríveis, muitos são dispostos a ajudar ou ter um rápido bate-papo que pode fazer a diferença na sua carreira.&lt;/p&gt;

&lt;p&gt;Por causa dessas interações, tive mentorias, peguei insights de uma galera &lt;strong&gt;FODA&lt;/strong&gt;, fui convidada para eventos online e muitas outras oportunidades que nunca teria tido sem a ajuda da comunidade.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0980hhxm1ymziz2v301f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0980hhxm1ymziz2v301f.jpg" alt="Picture of a developers meetup where I participated as a speaker" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não consigo &lt;strong&gt;enfatizar&lt;/strong&gt; o suficiente como é &lt;strong&gt;importante&lt;/strong&gt;, independentemente do seu conteúdo, número de seguidores ou quantidade de curtidas, fazer &lt;strong&gt;conexões&lt;/strong&gt; com outras pessoas. No final, é isso que realmente importa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumindo&lt;/strong&gt;, esses são os passos que considero fundamentais para ter &lt;strong&gt;sucesso&lt;/strong&gt; em todas essas dicas até agora:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Escolha seu &lt;strong&gt;nicho&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Ache pessoas &lt;strong&gt;referências&lt;/strong&gt; nele&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interaja&lt;/strong&gt; com o conteúdo dessas pessoas&lt;/li&gt;
&lt;li&gt;Crie seu &lt;strong&gt;próprio&lt;/strong&gt; conteúdo&lt;/li&gt;
&lt;li&gt;Se mantenha &lt;strong&gt;consistente&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Interaja com a &lt;strong&gt;comunidade&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Seguindo os passos &lt;strong&gt;1&lt;/strong&gt; a &lt;strong&gt;3&lt;/strong&gt;, é garantido que você comece a chamar atenção para a sua conta. Seu trabalho agora é converter essa &lt;em&gt;atenção&lt;/em&gt; para &lt;em&gt;followers&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;No passo 4, se atente a &lt;strong&gt;produzir valor&lt;/strong&gt; e &lt;strong&gt;focar no seu nicho&lt;/strong&gt; específico. Seja original e poste as coisas de forma autêntica, sempre guarde um tempinho para planejar o seu próximo passo. Isso vai fazer com que as pessoas queiram te seguir e interagir com o seu conteúdo.&lt;/p&gt;

&lt;p&gt;Para os passos 5 e 6, tente &lt;strong&gt;postar todo dia&lt;/strong&gt;. Isso vai fazer com que as pessoas vejam mais de você e aumentar a chance de se tornar um seguidor. Responda os comentários que puder e interaja com seus seguidores. Ninguém gosta de seguir uma conta fantasma! &lt;/p&gt;

&lt;h2&gt;
  
  
  Levando um Hobby a Sério &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Criar uma presença online foi um processo que me ensinou muito, mas que por muito tempo encarei apenas como um &lt;strong&gt;hobby&lt;/strong&gt;, que me motivava a programar de forma consistente. Eu apenas fazia porque &lt;strong&gt;gostava&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mas como isso me levou para DevRel?&lt;/p&gt;

&lt;p&gt;Quando estava saindo de um estágio como desenvolvedora de software, recebi uma proposta para trabalhar meio período como gerente de comunidade para uma startup canadense chamada &lt;a href="https://www.shakudo.io/" rel="noopener noreferrer"&gt;Shakudo&lt;/a&gt;, onde trabalho até hoje. Obviamente fiquei muito animada com a proposta de trabalhar pra &lt;strong&gt;fora do país&lt;/strong&gt; e ainda mais com algo que eu já gostava de fazer de graça.&lt;/p&gt;

&lt;p&gt;Nesse período me formei em Ciência e Tecnologia da Computação na UFRN, que é um generalista para entrar no meu atual curso Engenharia da Computação. Eventualmente, as &lt;strong&gt;habilidades técnicas&lt;/strong&gt; que construí durante os anos sozinha e na faculdade, junto com a minha experiência com criação de comunidades, me ajudaram a entrar integralmente como &lt;strong&gt;Developer Advocate na Shakudo&lt;/strong&gt; 🎉 &lt;/p&gt;

&lt;p&gt;Agora, sou responsável por fazer &lt;strong&gt;demos com o produto&lt;/strong&gt;, &lt;strong&gt;criar estudos de caso&lt;/strong&gt;, &lt;strong&gt;escrever documentação&lt;/strong&gt; e gerenciar várias iniciativas, certificando que estão &lt;strong&gt;alinhadas&lt;/strong&gt; aos objetivos da empresa. Irei falar mais sobre meu dia-a-dia como Developer Advocate em futuros posts do DevRel Brasil.&lt;/p&gt;

&lt;p&gt;A maior parte do meu time trabalha presencial no Canadá então muitas vezes estou assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawhus4ijzzk3gy5lay6l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawhus4ijzzk3gy5lay6l.jpg" alt="Online meeting with me on a huge TV" width="800" height="710"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas Sabrina, eu &lt;strong&gt;PRECISO&lt;/strong&gt; criar uma audiência própria para trabalhar em DevRel? &lt;/p&gt;

&lt;p&gt;A resposta é: &lt;strong&gt;NÃO!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Não é necessário ter qualquer influência online para ser um bom DevRel, até porque não vai ser todo mundo que quer se expor publicamente assim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PORÉM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se você quer trabalhar nessa área, é bom ter algum &lt;strong&gt;histórico de sucesso&lt;/strong&gt; criando conteúdo e desenvolvendo comunidades, além das skills técnicas. &lt;/p&gt;

&lt;p&gt;Falo sobre presença online pois é o método que funcionou para mim e para dezenas de conhecidos que trabalham com DevRel hoje. &lt;strong&gt;Contudo&lt;/strong&gt;, diria que esse não é o caso para uma grande parte de profissionais DevRel. Como existem diversas portas de entrada, tudo depende de você e como você quer construir a sua carreira.&lt;/p&gt;

&lt;h2&gt;
  
  
  MUITA Coisa pra Aprender &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Com certeza, há &lt;strong&gt;muitas&lt;/strong&gt; coisas que você precisa aprender para ter sucesso em DevRel. É normal que algumas delas sejam mais fáceis para você do que outras, por isso minha dica é:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Faça algo ruim com esforço para depois fazer algo bom sem esforço."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpv352jhztnjrc2wprlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpv352jhztnjrc2wprlf.png" alt="meme Ok ima google my error - damn all links are purple" width="680" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não tente alcançar a perfeição logo de cara. Se você fizer algo que não parece tão bom agora, mas que pode ser melhorado, &lt;strong&gt;poste&lt;/strong&gt;, analise o que pode ser aprimorado e vá melhorando com o tempo. Lembre que Roma não foi construída em um dia.&lt;/p&gt;

&lt;p&gt;Acredite, esse processo eventualmente se tornará natural para você, aumentando a quantidade de conteúdo de qualidade que você vai conseguir gerar em pouco tempo.&lt;/p&gt;

&lt;p&gt;Não deixe de postar o seu processo de aprendizagem nas redes sociais. Além de ser um &lt;strong&gt;ótimo&lt;/strong&gt; tipo de conteúdo, é bastante &lt;strong&gt;motivador&lt;/strong&gt; para quem gostaria de fazer algo semelhante.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumindo: Como Começar uma Comunidade &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Se você ainda não tem uma presença online e está se perguntando como começar do zero a sua própria marca pessoal ou comunidade de desenvolvedores, aqui estão algumas coisas que você deve considerar antes de começar adoidado:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Planeje sua rede social&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aqui eu falo bastante sobre o Twitter, pois acaba sendo a rede que gosto mais e que me proporcionou diversas &lt;strong&gt;oportunidades&lt;/strong&gt;. Isso não significa que outras redes também não tenham oportunidades incríveis para o crescimento pessoal e de uma comunidade. Outros exemplos são: &lt;strong&gt;Instagram&lt;/strong&gt;, &lt;strong&gt;Twitch&lt;/strong&gt;, &lt;strong&gt;Reddit&lt;/strong&gt;, &lt;strong&gt;Youtube&lt;/strong&gt; e &lt;strong&gt;Discord&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foz64ijw8zivr6eozas1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foz64ijw8zivr6eozas1r.png" alt="redes sociais" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Antes te começar, &lt;strong&gt;analise&lt;/strong&gt; qual se encaixa melhor no seu perfil e que tipo de conteúdo gostaria de produzir. Aqui estão alguns exemplos de comunidades de desenvolvedores bem sucedidas nessas outras redes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Javascript Wizz &lt;a href="https://instagram.com/javascript_wizz?igshid=YmMyMTA2M2Y=" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Midudev &lt;a href="https://www.twitch.tv/midudev" rel="noopener noreferrer"&gt;Twitch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;WebDev &lt;a href="https://www.reddit.com/r/webdev/" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Joma Tech &lt;a href="https://www.youtube.com/@jomaoppa" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;He4art Developers &lt;a href="https://discord.gg/he4rt" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Comece pequeno&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Colocar objetivos grandes logo de cara pode facilmente levar a frustração, desmotivação ou &lt;strong&gt;burnout&lt;/strong&gt;. Você tem mais chances de se dar melhor se focar em ganhar &lt;strong&gt;10&lt;/strong&gt; followers ou membros em 1 semana, do que &lt;strong&gt;10,000&lt;/strong&gt; em um ano. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Mantenha Consistência&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Não custa nada repetir o quanto isso é essencial. Um dos métodos que utilizei para me manter consistente foi a hashtag &lt;strong&gt;#100DaysOfCode&lt;/strong&gt;. Independente do que você escolha para isso, e importante é &lt;strong&gt;aparecer&lt;/strong&gt; todo dia, e criar um pouquinho de valor para a comunidade.&lt;/p&gt;

&lt;p&gt;Entenda o seu &lt;strong&gt;nicho&lt;/strong&gt; comunidade, estude o que outras pessoas estão fazendo e &lt;strong&gt;aplique&lt;/strong&gt; esse conhecimento no seu conteúdo &lt;strong&gt;consistentemente&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Inove&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ter um &lt;strong&gt;diferencial&lt;/strong&gt; é um fator importante para escalar sua comunidade. Se pergunte: já existem muitas comunidades lá fora que desenvolvedores podem participar. &lt;strong&gt;Por que eles escolheriam participar da sua?&lt;/strong&gt; Pense em algo que você gostaria de ver acontecendo hoje que ainda não tenha muito suporte. &lt;/p&gt;

&lt;p&gt;Pode ser um projeto &lt;strong&gt;open-source&lt;/strong&gt; que ajudaria muita gente a começar em alguma linguagem. Ou uma forma de facilitar a entrada e pessoas transacionando a carreira para tech &lt;strong&gt;depois dos 30&lt;/strong&gt;. Talvez uma comunidade totalmente focada em criar coisas &lt;strong&gt;no-code&lt;/strong&gt; ou com &lt;strong&gt;inteligência artificial&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Escolha algo que você tenha &lt;strong&gt;afinidade&lt;/strong&gt; e crie algo novo que &lt;strong&gt;você&lt;/strong&gt; gostaria de ver dentro daquela área. As chances são que muita gente também gostaria de participar da sua ideia.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Compartilhei aqui um pouco da minha experiência e de muitas pequenas coisas que me levaram a conseguir trilhar uma carreira internacional enquanto ainda termino a faculdade de Engenharia de Computação.&lt;/p&gt;

&lt;p&gt;No entanto, a dica mais &lt;strong&gt;valiosa&lt;/strong&gt; que aprendi até hoje e que pode ajudar em qualquer carreira e na vida em geral é: &lt;strong&gt;esteja sempre pronto para falhar e aprender&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Se você aprender constantemente, trabalhar duro, e não ser um cuzão, as chances de você ser extremamente bem sucedido em DevRel ou em &lt;strong&gt;qualquer outra carreira&lt;/strong&gt; são enormes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhsbs3g5da0jwvxkoo1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhsbs3g5da0jwvxkoo1b.png" alt="bro relax i'm just good at googling meme" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Espero que esse post tenha te ajudado a entender um pouco mais sobre a importância da criação de uma presença online, e no melhor dos casos, seja a sementinha de motivação para alguém começar a construir sua própria comunidade de desenvolvedores.&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
  </channel>
</rss>
