<!-- CANARY: REQ=REQ-HNSW-INDEX-OPTIMIZER-INTEGRATION-001; FEATURE="HNSW IndexOptimizer Integration"; ASPECT=ProductionIntegration; STATUS=TESTED; OWNER=vector; UPDATED=2025-10-05 -->
<h2 id="vector-similarity-search-tutorial" class="position-relative d-flex align-items-center group">
<span>Vector Similarity Search Tutorial</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="vector-similarity-search-tutorial"
aria-haspopup="dialog"
aria-label="Share link: Vector Similarity Search Tutorial">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h2><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden>
<div class="hsm-dialog" role="document">
<div class="hsm-header">
<h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2>
<button type="button" class="hsm-close" aria-label="Close">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<div class="hsm-body">
<label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label>
<div class="input-group mb-4 hsm-url-group">
<input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" />
<button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy">
<i class="fa-duotone fa-clipboard" aria-hidden="true"></i>
</button>
</div>
<div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div>
<div class="hsm-share-grid">
<a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-twitter me-2"></i>Twitter
</a>
<a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-linkedin me-2"></i>LinkedIn
</a>
<a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-facebook me-2"></i>Facebook
</a>
</div>
</div>
</div>
</div>
<style>
.heading-share-modal {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.6);
z-index: 1050;
padding: 1rem;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
.heading-share-modal[hidden] { display: none !important; }
.hsm-dialog {
max-width: 420px;
width: 100%;
background: var(--bs-body-bg, #fff);
color: var(--bs-body-color, #212529);
border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
animation: hsm-fade-in 0.2s ease-out;
}
@keyframes hsm-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
[data-bs-theme="dark"] .hsm-dialog {
background: #1e293b;
border-color: rgba(255,255,255,0.1);
color: #f8f9fa;
}
.hsm-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
background: rgba(0,0,0,0.02);
}
[data-bs-theme="dark"] .hsm-header {
background: rgba(255,255,255,0.02);
border-color: rgba(255,255,255,0.1);
}
.hsm-close {
background: transparent;
border: none;
color: inherit;
opacity: 0.5;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 1.2rem;
line-height: 1;
transition: opacity 0.2s;
}
.hsm-close:hover {
opacity: 1;
}
.hsm-body {
padding: 1.5rem;
}
.hsm-url-group {
display: flex !important;
align-items: stretch;
}
.hsm-url-group .form-control {
flex: 1;
min-width: 0;
margin: 0;
background: var(--bs-secondary-bg, #f8f9fa);
border-color: var(--bs-border-color, #dee2e6);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
height: 42px;
}
.hsm-url-group .btn {
flex: 0 0 auto;
margin: 0;
margin-left: -1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 1.25rem;
z-index: 2;
}
[data-bs-theme="dark"] .hsm-url-group .form-control {
background: #0f172a;
border-color: #334155;
color: #e2e8f0;
}
.hsm-share-grid {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.hsm-share-grid .btn {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
padding: 0.6rem;
border-color: var(--bs-border-color);
width: 100%;
}
[data-bs-theme="dark"] .hsm-share-grid .btn {
color: #e2e8f0;
border-color: #475569;
}
[data-bs-theme="dark"] .hsm-share-grid .btn:hover {
background: #334155;
border-color: #cbd5e1;
}
</style>
<script>
(function(){
const modal = document.getElementById('headingShareModal');
if(!modal) return;
const input = modal.querySelector('#headingShareInput');
const copyBtn = modal.querySelector('.hsm-copy');
const twitter = modal.querySelector('#share-twitter');
const linkedin = modal.querySelector('#share-linkedin');
const facebook = modal.querySelector('#share-facebook');
const closeBtn = modal.querySelector('.hsm-close');
let lastFocus=null;
let trapBound=false;
function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; }
function isOpen(){ return !modal.hasAttribute('hidden'); }
function hydrate(id){
const url=buildUrl(id);
input.value=url;
const enc=encodeURIComponent(url);
const text=encodeURIComponent(document.title);
if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`;
if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`;
if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`;
}
function openModal(id){
lastFocus=document.activeElement;
hydrate(id);
if(!isOpen()){
modal.removeAttribute('hidden');
}
requestAnimationFrame(()=>{ input.focus(); });
trapFocus();
}
function closeModal(){
if(!isOpen()) return;
modal.setAttribute('hidden','');
if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus();
}
function copyCurrent(){
try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); }
catch(e){ fallback(); }
}
function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} }
function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); }
function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); }
function bindShareButtons(){
document.querySelectorAll('.h-share').forEach(btn=>{
if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; }
});
}
bindShareButtons();
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', bindShareButtons);
} else {
requestAnimationFrame(bindShareButtons);
}
document.addEventListener('click', function(e){
const shareBtn=e.target.closest && e.target.closest('.h-share');
if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); }
}, true);
document.addEventListener('click', e=>{
if(e.target===modal) closeModal();
if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); }
if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); }
});
document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); });
function trapFocus(){
if(trapBound) return;
trapBound=true;
modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } });
}
if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); });
})();
</script><p>Learn to implement semantic search using vector embeddings and HNSW indexing in this hands-on 25-minute tutorial.</p>
<h3 id="prerequisites" class="position-relative d-flex align-items-center group">
<span>Prerequisites</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="prerequisites"
aria-haspopup="dialog"
aria-label="Share link: Prerequisites">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li>Completed <a
href="/docs/tutorials/match-basics/"
>MATCH Basics Tutorial</a>
</li>
<li>Python 3.9+ with pip installed</li>
<li>Geode server running (<code>geode serve</code>)</li>
<li>Basic understanding of embeddings (helpful but not required)</li>
</ul>
<h3 id="tutorial-overview" class="position-relative d-flex align-items-center group">
<span>Tutorial Overview</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="tutorial-overview"
aria-haspopup="dialog"
aria-label="Share link: Tutorial Overview">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p><strong>Time</strong>: 25 minutes
<strong>Difficulty</strong>: Intermediate
<strong>Topics</strong>: Vector embeddings, HNSW indexing, similarity metrics, semantic search</p>
<p>By the end of this tutorial, you’ll be able to:</p>
<ul>
<li>Generate vector embeddings from text</li>
<li>Store vectors in Geode</li>
<li>Create HNSW indexes for fast similarity search</li>
<li>Find semantically similar items</li>
<li>Optimize vector search performance</li>
</ul>
<h3 id="what-are-vector-embeddings" class="position-relative d-flex align-items-center group">
<span>What are Vector Embeddings?</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="what-are-vector-embeddings"
aria-haspopup="dialog"
aria-label="Share link: What are Vector Embeddings?">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Vector embeddings convert data (text, images, audio) into numerical arrays that capture semantic meaning. Similar items have vectors that are close in vector space.</p>
<p><strong>Example</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">"cat" → [0.2, 0.8, 0.1, ...]
</span></span><span class="line"><span class="cl">"dog" → [0.3, 0.7, 0.2, ...] (close to "cat")
</span></span><span class="line"><span class="cl">"car" → [0.9, 0.1, 0.8, ...] (far from "cat")
</span></span></code></pre></div>
<h3 id="step-1-setup-environment" class="position-relative d-flex align-items-center group">
<span>Step 1: Setup Environment</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-1-setup-environment"
aria-haspopup="dialog"
aria-label="Share link: Step 1: Setup Environment">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="install-dependencies" class="position-relative d-flex align-items-center group">
<span>Install Dependencies</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="install-dependencies"
aria-haspopup="dialog"
aria-label="Share link: Install Dependencies">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Install Python client and embedding library</span>
</span></span><span class="line"><span class="cl">pip install geode-client sentence-transformers
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Or if using requirements file</span>
</span></span><span class="line"><span class="cl">cat > requirements.txt <span class="s"><<EOF
</span></span></span><span class="line"><span class="cl"><span class="s">geode-client>=0.1.0
</span></span></span><span class="line"><span class="cl"><span class="s">sentence-transformers>=2.2.0
</span></span></span><span class="line"><span class="cl"><span class="s">numpy>=1.21.0
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">pip install -r requirements.txt
</span></span></code></pre></div>
<h4 id="import-libraries" class="position-relative d-flex align-items-center group">
<span>Import Libraries</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="import-libraries"
aria-haspopup="dialog"
aria-label="Share link: Import Libraries">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><!-- CANARY: REQ=REQ-CLIENT-PY-001; FEATURE="PythonClientConnection"; ASPECT=HelloHandshake; STATUS=IMPL; OWNER=clients; UPDATED=2025-02-14 -->
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">asyncio</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">sentence_transformers</span> <span class="kn">import</span> <span class="n">SentenceTransformer</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create client (use an async connection for queries)</span>
</span></span><span class="line"><span class="cl"><span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s2">"localhost"</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">3141</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Load embedding model (downloads on first use, ~80MB)</span>
</span></span><span class="line"><span class="cl"><span class="n">model</span> <span class="o">=</span> <span class="n">SentenceTransformer</span><span class="p">(</span><span class="s1">'all-MiniLM-L6-v2'</span><span class="p">)</span>
</span></span></code></pre></div><p>All Python steps below assume you are inside an async context, for example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Run the steps below with await conn.execute(...) / await conn.query(...)</span>
</span></span><span class="line"><span class="cl"> <span class="o">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</span></span></code></pre></div>
<h4 id="verify-setup" class="position-relative d-flex align-items-center group">
<span>Verify Setup</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="verify-setup"
aria-haspopup="dialog"
aria-label="Share link: Verify Setup">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Test embedding generation</span>
</span></span><span class="line"><span class="cl"><span class="n">text</span> <span class="o">=</span> <span class="s2">"Hello, world!"</span>
</span></span><span class="line"><span class="cl"><span class="n">embedding</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Text: </span><span class="si">{</span><span class="n">text</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Embedding shape: </span><span class="si">{</span><span class="n">embedding</span><span class="o">.</span><span class="n">shape</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Embedding (first 5 dims): </span><span class="si">{</span><span class="n">embedding</span><span class="p">[:</span><span class="mi">5</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Expected output:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Text: Hello, world!</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Embedding shape: (384,)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Embedding (first 5 dims): [0.123, -0.456, 0.789, ...]</span>
</span></span></code></pre></div>
<h3 id="step-2-create-sample-dataset" class="position-relative d-flex align-items-center group">
<span>Step 2: Create Sample Dataset</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-2-create-sample-dataset"
aria-haspopup="dialog"
aria-label="Share link: Step 2: Create Sample Dataset">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="create-movie-database" class="position-relative d-flex align-items-center group">
<span>Create Movie Database</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="create-movie-database"
aria-haspopup="dialog"
aria-label="Share link: Create Movie Database">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Sample movies with descriptions</span>
</span></span><span class="line"><span class="cl"><span class="n">movies</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"id"</span><span class="p">:</span> <span class="s2">"mov_1"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"title"</span><span class="p">:</span> <span class="s2">"The Matrix"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"description"</span><span class="p">:</span> <span class="s2">"A computer hacker learns about the true nature of reality and his role in the war against its controllers."</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"genre"</span><span class="p">:</span> <span class="s2">"Sci-Fi"</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"id"</span><span class="p">:</span> <span class="s2">"mov_2"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"title"</span><span class="p">:</span> <span class="s2">"Inception"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"description"</span><span class="p">:</span> <span class="s2">"A thief who steals corporate secrets through dream-sharing technology is given the task of planting an idea."</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"genre"</span><span class="p">:</span> <span class="s2">"Sci-Fi"</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"id"</span><span class="p">:</span> <span class="s2">"mov_3"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"title"</span><span class="p">:</span> <span class="s2">"The Shawshank Redemption"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"description"</span><span class="p">:</span> <span class="s2">"Two imprisoned men bond over years, finding solace and eventual redemption through acts of common decency."</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"genre"</span><span class="p">:</span> <span class="s2">"Drama"</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"id"</span><span class="p">:</span> <span class="s2">"mov_4"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"title"</span><span class="p">:</span> <span class="s2">"The Dark Knight"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"description"</span><span class="p">:</span> <span class="s2">"Batman faces the Joker, a criminal mastermind who wants to plunge Gotham City into anarchy."</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"genre"</span><span class="p">:</span> <span class="s2">"Action"</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"id"</span><span class="p">:</span> <span class="s2">"mov_5"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"title"</span><span class="p">:</span> <span class="s2">"Interstellar"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"description"</span><span class="p">:</span> <span class="s2">"A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival."</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"genre"</span><span class="p">:</span> <span class="s2">"Sci-Fi"</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"id"</span><span class="p">:</span> <span class="s2">"mov_6"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"title"</span><span class="p">:</span> <span class="s2">"Forrest Gump"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"description"</span><span class="p">:</span> <span class="s2">"The presidencies of Kennedy and Johnson unfold through the perspective of an Alabama man with an IQ of 75."</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"genre"</span><span class="p">:</span> <span class="s2">"Drama"</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Generate embeddings</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">"Generating embeddings..."</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">movie</span> <span class="ow">in</span> <span class="n">movies</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Create embedding from title + description</span>
</span></span><span class="line"><span class="cl"> <span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">movie</span><span class="p">[</span><span class="s1">'title'</span><span class="p">]</span><span class="si">}</span><span class="s2">. </span><span class="si">{</span><span class="n">movie</span><span class="p">[</span><span class="s1">'description'</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span>
</span></span><span class="line"><span class="cl"> <span class="n">movie</span><span class="p">[</span><span class="s1">'embedding'</span><span class="p">]</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">text</span><span class="p">)</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"✓ </span><span class="si">{</span><span class="n">movie</span><span class="p">[</span><span class="s1">'title'</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span></code></pre></div>
<h4 id="load-into-geode" class="position-relative d-flex align-items-center group">
<span>Load into Geode</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="load-into-geode"
aria-haspopup="dialog"
aria-label="Share link: Load into Geode">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Create graph</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"CREATE GRAPH MovieSearch; USE MovieSearch;"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Insert movies with embeddings</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">movie</span> <span class="ow">in</span> <span class="n">movies</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (:Movie {
</span></span></span><span class="line"><span class="cl"><span class="s2"> id: $id,
</span></span></span><span class="line"><span class="cl"><span class="s2"> title: $title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> description: $description,
</span></span></span><span class="line"><span class="cl"><span class="s2"> genre: $genre,
</span></span></span><span class="line"><span class="cl"><span class="s2"> embedding: $embedding
</span></span></span><span class="line"><span class="cl"><span class="s2"> })
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="n">movie</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">✓ Loaded </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">movies</span><span class="p">)</span><span class="si">}</span><span class="s2"> movies into Geode"</span><span class="p">)</span>
</span></span></code></pre></div>
<h3 id="step-3-create-hnsw-index" class="position-relative d-flex align-items-center group">
<span>Step 3: Create HNSW Index</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-3-create-hnsw-index"
aria-haspopup="dialog"
aria-label="Share link: Step 3: Create HNSW Index">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="understanding-hnsw" class="position-relative d-flex align-items-center group">
<span>Understanding HNSW</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="understanding-hnsw"
aria-haspopup="dialog"
aria-label="Share link: Understanding HNSW">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>HNSW</strong> (Hierarchical Navigable Small World) is a graph-based algorithm for approximate nearest neighbor search:</p>
<ul>
<li><strong>Hierarchical</strong>: Multi-layer graph structure</li>
<li><strong>Navigable</strong>: Efficiently finds approximate neighbors</li>
<li><strong>Small World</strong>: Short paths between any two points</li>
<li><strong>Performance</strong>: O(log n) search time</li>
</ul>
<h4 id="create-vector-index" class="position-relative d-flex align-items-center group">
<span>Create Vector Index</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="create-vector-index"
aria-haspopup="dialog"
aria-label="Share link: Create Vector Index">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Create</span><span class="w"> </span><span class="py">HNSW</span><span class="w"> </span><span class="py">index</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">embedding</span><span class="w"> </span><span class="py">field</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">movie_embedding_idx</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Movie</span><span class="p">(</span><span class="py">embedding</span><span class="p">)</span><span class="w"> </span><span class="py">USING</span><span class="w"> </span><span class="py">vector</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p>In Python:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Create vector index</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE INDEX movie_embedding_idx ON Movie(embedding) USING vector
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">"✓ Created HNSW vector index"</span><span class="p">)</span>
</span></span></code></pre></div>
<h4 id="index-parameters-optional" class="position-relative d-flex align-items-center group">
<span>Index Parameters (Optional)</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="index-parameters-optional"
aria-haspopup="dialog"
aria-label="Share link: Index Parameters (Optional)">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Advanced: Configure HNSW parameters</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE INDEX movie_embedding_advanced_idx ON Movie(embedding) USING vector
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH {
</span></span></span><span class="line"><span class="cl"><span class="s2"> m: 16, -- Max connections per layer (default: 16)
</span></span></span><span class="line"><span class="cl"><span class="s2"> ef_construction: 200, -- Size of dynamic candidate list (default: 200)
</span></span></span><span class="line"><span class="cl"><span class="s2"> ef_search: 100 -- Search-time candidate list size (default: 100)
</span></span></span><span class="line"><span class="cl"><span class="s2"> }
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span></code></pre></div><p><strong>Parameters</strong>:</p>
<ul>
<li><code>m</code>: Higher = better recall, more memory (typical: 12-48)</li>
<li><code>ef_construction</code>: Higher = better index quality, slower build (typical: 100-400)</li>
<li><code>ef_search</code>: Higher = better accuracy, slower search (typical: 50-200)</li>
</ul>
<h3 id="step-4-similarity-search" class="position-relative d-flex align-items-center group">
<span>Step 4: Similarity Search</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-4-similarity-search"
aria-haspopup="dialog"
aria-label="Share link: Step 4: Similarity Search">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="find-similar-movies" class="position-relative d-flex align-items-center group">
<span>Find Similar Movies</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="find-similar-movies"
aria-haspopup="dialog"
aria-label="Share link: Find Similar Movies">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Query: "space exploration adventure"</span>
</span></span><span class="line"><span class="cl"><span class="n">query_text</span> <span class="o">=</span> <span class="s2">"space exploration adventure"</span>
</span></span><span class="line"><span class="cl"><span class="n">query_embedding</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">query_text</span><span class="p">)</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Find similar movies using cosine distance</span>
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE vector_distance_cosine(m.embedding, $query_vec) < 0.5
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> m.description,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_distance_cosine(m.embedding, $query_vec) AS distance
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY distance ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 5
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Query: '</span><span class="si">{</span><span class="n">query_text</span><span class="si">}</span><span class="s2">'"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Most similar movies:"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">rows</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">title</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"m.title"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="n">distance</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"distance"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="n">description</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"m.description"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">. </span><span class="si">{</span><span class="n">title</span><span class="si">}</span><span class="s2"> (distance: </span><span class="si">{</span><span class="n">distance</span><span class="si">:</span><span class="s2">.3f</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">" </span><span class="si">{</span><span class="n">description</span><span class="p">[:</span><span class="mi">80</span><span class="p">]</span><span class="si">}</span><span class="s2">..."</span><span class="p">)</span>
</span></span></code></pre></div><p><strong>Expected output</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Query: 'space exploration adventure'
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Most similar movies:
</span></span><span class="line"><span class="cl">1. Interstellar (distance: 0.156)
</span></span><span class="line"><span class="cl"> A team of explorers travel through a wormhole in space in an attempt to ensure...
</span></span><span class="line"><span class="cl">2. The Matrix (distance: 0.312)
</span></span><span class="line"><span class="cl"> A computer hacker learns about the true nature of reality and his role in the...
</span></span><span class="line"><span class="cl">3. Inception (distance: 0.389)
</span></span><span class="line"><span class="cl"> A thief who steals corporate secrets through dream-sharing technology is given...
</span></span></code></pre></div>
<h4 id="understanding-distance-metrics" class="position-relative d-flex align-items-center group">
<span>Understanding Distance Metrics</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="understanding-distance-metrics"
aria-haspopup="dialog"
aria-label="Share link: Understanding Distance Metrics">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4>
<h5 id="cosine-distance" class="position-relative d-flex align-items-center group">
<span>Cosine Distance</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="cosine-distance"
aria-haspopup="dialog"
aria-label="Share link: Cosine Distance">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Cosine distance: 1 - cosine_similarity</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Range: [0, 2], where 0 = identical, 2 = opposite</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Best for: Text embeddings (direction matters more than magnitude)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_distance_cosine(m.embedding, $query_vec) AS cosine_dist
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY cosine_dist ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 5
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span></code></pre></div>
<h5 id="l2-distance-euclidean" class="position-relative d-flex align-items-center group">
<span>L2 Distance (Euclidean)</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="l2-distance-euclidean"
aria-haspopup="dialog"
aria-label="Share link: L2 Distance (Euclidean)">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># L2 distance: sqrt(sum((a-b)^2))</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Range: [0, ∞], where 0 = identical</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Best for: When magnitude matters (e.g., image embeddings)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_distance_l2(m.embedding, $query_vec) AS l2_dist
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY l2_dist ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 5
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span></code></pre></div>
<h5 id="inner-product" class="position-relative d-flex align-items-center group">
<span>Inner Product</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="inner-product"
aria-haspopup="dialog"
aria-label="Share link: Inner Product">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Inner product: sum(a * b)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Range: [-∞, ∞], where higher = more similar</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Best for: When embeddings are normalized</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_inner_product(m.embedding, $query_vec) AS similarity
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY similarity DESC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 5
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span></code></pre></div>
<h3 id="step-5-hybrid-search" class="position-relative d-flex align-items-center group">
<span>Step 5: Hybrid Search</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-5-hybrid-search"
aria-haspopup="dialog"
aria-label="Share link: Step 5: Hybrid Search">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="combine-vector-and-keyword-search" class="position-relative d-flex align-items-center group">
<span>Combine Vector and Keyword Search</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="combine-vector-and-keyword-search"
aria-haspopup="dialog"
aria-label="Share link: Combine Vector and Keyword Search">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Hybrid search: Vector similarity + keyword filter</span>
</span></span><span class="line"><span class="cl"><span class="n">query_text</span> <span class="o">=</span> <span class="s2">"mind-bending reality"</span>
</span></span><span class="line"><span class="cl"><span class="n">query_embedding</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">query_text</span><span class="p">)</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE m.genre = 'Sci-Fi'
</span></span></span><span class="line"><span class="cl"><span class="s2"> AND vector_distance_cosine(m.embedding, $query_vec) < 0.6
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> m.genre,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_distance_cosine(m.embedding, $query_vec) AS distance
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY distance ASC
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Query: '</span><span class="si">{</span><span class="n">query_text</span><span class="si">}</span><span class="s2">' (Genre: Sci-Fi)"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">title</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"m.title"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="n">distance</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"distance"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"• </span><span class="si">{</span><span class="n">title</span><span class="si">}</span><span class="s2"> (distance: </span><span class="si">{</span><span class="n">distance</span><span class="si">:</span><span class="s2">.3f</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
</span></span></code></pre></div>
<h4 id="weighted-combination" class="position-relative d-flex align-items-center group">
<span>Weighted Combination</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="weighted-combination"
aria-haspopup="dialog"
aria-label="Share link: Weighted Combination">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Combine vector similarity with rating score</span>
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH m,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_distance_cosine(m.embedding, $query_vec) AS vec_dist,
</span></span></span><span class="line"><span class="cl"><span class="s2"> m.rating AS rating
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vec_dist,
</span></span></span><span class="line"><span class="cl"><span class="s2"> rating,
</span></span></span><span class="line"><span class="cl"><span class="s2"> (vec_dist * 0.7 + (1 - rating/10) * 0.3) AS combined_score
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY combined_score ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 5
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span></code></pre></div>
<h3 id="step-6-advanced-patterns" class="position-relative d-flex align-items-center group">
<span>Step 6: Advanced Patterns</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-6-advanced-patterns"
aria-haspopup="dialog"
aria-label="Share link: Step 6: Advanced Patterns">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="batch-similarity-search" class="position-relative d-flex align-items-center group">
<span>Batch Similarity Search</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="batch-similarity-search"
aria-haspopup="dialog"
aria-label="Share link: Batch Similarity Search">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Find similar items for multiple queries at once</span>
</span></span><span class="line"><span class="cl"><span class="n">queries</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"space adventure"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"prison drama"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"superhero action"</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">query_text</span> <span class="ow">in</span> <span class="n">queries</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">query_emb</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">query_text</span><span class="p">)</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_distance_cosine(m.embedding, $query_vec) AS distance
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY distance ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 3
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_emb</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Query: '</span><span class="si">{</span><span class="n">query_text</span><span class="si">}</span><span class="s2">'"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">title</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"m.title"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="n">distance</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"distance"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">" • </span><span class="si">{</span><span class="n">title</span><span class="si">}</span><span class="s2"> (</span><span class="si">{</span><span class="n">distance</span><span class="si">:</span><span class="s2">.3f</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
</span></span></code></pre></div>
<h4 id="find-items-similar-to-an-existing-item" class="position-relative d-flex align-items-center group">
<span>Find Items Similar to an Existing Item</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="find-items-similar-to-an-existing-item"
aria-haspopup="dialog"
aria-label="Share link: Find Items Similar to an Existing Item">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># "More like this" - Find movies similar to The Matrix</span>
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (ref:Movie {title: 'The Matrix'})
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (similar:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE similar <> ref
</span></span></span><span class="line"><span class="cl"><span class="s2"> AND vector_distance_cosine(similar.embedding, ref.embedding) < 0.4
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN similar.title,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_distance_cosine(similar.embedding, ref.embedding) AS distance
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY distance ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 5
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Movies similar to 'The Matrix':"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">title</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"similar.title"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="n">distance</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"distance"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"• </span><span class="si">{</span><span class="n">title</span><span class="si">}</span><span class="s2"> (distance: </span><span class="si">{</span><span class="n">distance</span><span class="si">:</span><span class="s2">.3f</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
</span></span></code></pre></div>
<h4 id="clustering-similar-items" class="position-relative d-flex align-items-center group">
<span>Clustering Similar Items</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="clustering-similar-items"
aria-haspopup="dialog"
aria-label="Share link: Clustering Similar Items">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Use K-means clustering (external library)</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">sklearn.cluster</span> <span class="kn">import</span> <span class="n">KMeans</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get all embeddings</span>
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.id, m.title, m.embedding
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">embeddings</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="n">row</span><span class="p">[</span><span class="s2">"m.embedding"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">rows</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">movie_ids</span> <span class="o">=</span> <span class="p">[</span><span class="n">row</span><span class="p">[</span><span class="s2">"m.id"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">titles</span> <span class="o">=</span> <span class="p">[</span><span class="n">row</span><span class="p">[</span><span class="s2">"m.title"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Cluster into 2 groups</span>
</span></span><span class="line"><span class="cl"><span class="n">kmeans</span> <span class="o">=</span> <span class="n">KMeans</span><span class="p">(</span><span class="n">n_clusters</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">42</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">clusters</span> <span class="o">=</span> <span class="n">kmeans</span><span class="o">.</span><span class="n">fit_predict</span><span class="p">(</span><span class="n">embeddings</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Store cluster assignments</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">movie_id</span><span class="p">,</span> <span class="n">cluster</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">movie_ids</span><span class="p">,</span> <span class="n">clusters</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie {id: $id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET m.cluster = $cluster
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s1">'id'</span><span class="p">:</span> <span class="n">movie_id</span><span class="p">,</span> <span class="s1">'cluster'</span><span class="p">:</span> <span class="nb">int</span><span class="p">(</span><span class="n">cluster</span><span class="p">)})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># View clusters</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">cluster_id</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Cluster </span><span class="si">{</span><span class="n">cluster_id</span><span class="si">}</span><span class="s2">:"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">cluster_titles</span> <span class="o">=</span> <span class="p">[</span><span class="n">t</span> <span class="k">for</span> <span class="n">t</span><span class="p">,</span> <span class="n">c</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">titles</span><span class="p">,</span> <span class="n">clusters</span><span class="p">)</span> <span class="k">if</span> <span class="n">c</span> <span class="o">==</span> <span class="n">cluster_id</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">title</span> <span class="ow">in</span> <span class="n">cluster_titles</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">" • </span><span class="si">{</span><span class="n">title</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span></code></pre></div>
<h3 id="step-7-performance-optimization" class="position-relative d-flex align-items-center group">
<span>Step 7: Performance Optimization</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-7-performance-optimization"
aria-haspopup="dialog"
aria-label="Share link: Step 7: Performance Optimization">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="index-tuning" class="position-relative d-flex align-items-center group">
<span>Index Tuning</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="index-tuning"
aria-haspopup="dialog"
aria-label="Share link: Index Tuning">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Profile query performance</span>
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> PROFILE
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE vector_distance_cosine(m.embedding, $query_vec) < 0.5
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title, vector_distance_cosine(m.embedding, $query_vec) AS dist
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY dist ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 10
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Check if index is used</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Look for "IndexScan [movie_embedding_idx]" in profile output</span>
</span></span></code></pre></div>
<h4 id="adjust-hnsw-parameters" class="position-relative d-flex align-items-center group">
<span>Adjust HNSW Parameters</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="adjust-hnsw-parameters"
aria-haspopup="dialog"
aria-label="Share link: Adjust HNSW Parameters">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Rebuild index with different parameters for better recall</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"DROP INDEX movie_embedding_idx"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE INDEX movie_embedding_idx ON Movie(embedding) USING vector
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH {
</span></span></span><span class="line"><span class="cl"><span class="s2"> m: 32, -- More connections = better recall
</span></span></span><span class="line"><span class="cl"><span class="s2"> ef_construction: 400, -- Higher quality index
</span></span></span><span class="line"><span class="cl"><span class="s2"> ef_search: 200 -- More thorough search
</span></span></span><span class="line"><span class="cl"><span class="s2"> }
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Trade-off: Better accuracy, but slower search and more memory</span>
</span></span></code></pre></div>
<h4 id="limit-search-space" class="position-relative d-flex align-items-center group">
<span>Limit Search Space</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="limit-search-space"
aria-haspopup="dialog"
aria-label="Share link: Limit Search Space">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Pre-filter with fast index before vector search</span>
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE m.genre = 'Sci-Fi' -- Fast index lookup first
</span></span></span><span class="line"><span class="cl"><span class="s2"> AND vector_distance_cosine(m.embedding, $query_vec) < 0.5
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY vector_distance_cosine(m.embedding, $query_vec) ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 10
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span></code></pre></div>
<h3 id="step-8-production-best-practices" class="position-relative d-flex align-items-center group">
<span>Step 8: Production Best Practices</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-8-production-best-practices"
aria-haspopup="dialog"
aria-label="Share link: Step 8: Production Best Practices">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="normalize-embeddings" class="position-relative d-flex align-items-center group">
<span>Normalize Embeddings</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="normalize-embeddings"
aria-haspopup="dialog"
aria-label="Share link: Normalize Embeddings">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Normalize vectors for consistent comparisons</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">normalize_embedding</span><span class="p">(</span><span class="n">embedding</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""L2 normalization"""</span>
</span></span><span class="line"><span class="cl"> <span class="n">norm</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">embedding</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span><span class="n">embedding</span> <span class="o">/</span> <span class="n">norm</span><span class="p">)</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span> <span class="k">if</span> <span class="n">norm</span> <span class="o">></span> <span class="mi">0</span> <span class="k">else</span> <span class="n">embedding</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Use normalized embeddings</span>
</span></span><span class="line"><span class="cl"><span class="n">text</span> <span class="o">=</span> <span class="s2">"example text"</span>
</span></span><span class="line"><span class="cl"><span class="n">embedding</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">normalized_emb</span> <span class="o">=</span> <span class="n">normalize_embedding</span><span class="p">(</span><span class="n">embedding</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (:Item {
</span></span></span><span class="line"><span class="cl"><span class="s2"> text: $text,
</span></span></span><span class="line"><span class="cl"><span class="s2"> embedding: $embedding
</span></span></span><span class="line"><span class="cl"><span class="s2"> })
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'text'</span><span class="p">:</span> <span class="n">text</span><span class="p">,</span> <span class="s1">'embedding'</span><span class="p">:</span> <span class="n">normalized_emb</span><span class="p">})</span>
</span></span></code></pre></div>
<h4 id="handle-missing-embeddings" class="position-relative d-flex align-items-center group">
<span>Handle Missing Embeddings</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="handle-missing-embeddings"
aria-haspopup="dialog"
aria-label="Share link: Handle Missing Embeddings">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Gracefully handle items without embeddings</span>
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE m.embedding IS NOT NULL
</span></span></span><span class="line"><span class="cl"><span class="s2"> AND vector_distance_cosine(m.embedding, $query_vec) < 0.5
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY vector_distance_cosine(m.embedding, $query_vec) ASC
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span></code></pre></div>
<h4 id="batch-embedding-generation" class="position-relative d-flex align-items-center group">
<span>Batch Embedding Generation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="batch-embedding-generation"
aria-haspopup="dialog"
aria-label="Share link: Batch Embedding Generation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Generate embeddings in batches for efficiency</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">batch_generate_embeddings</span><span class="p">(</span><span class="n">texts</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">32</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Generate embeddings in batches"""</span>
</span></span><span class="line"><span class="cl"> <span class="n">embeddings</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">texts</span><span class="p">),</span> <span class="n">batch_size</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">batch</span> <span class="o">=</span> <span class="n">texts</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span> <span class="o">+</span> <span class="n">batch_size</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="n">batch_embeddings</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">batch</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">embeddings</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">batch_embeddings</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">embeddings</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Use for large datasets</span>
</span></span><span class="line"><span class="cl"><span class="n">texts</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">m</span><span class="p">[</span><span class="s1">'title'</span><span class="p">]</span><span class="si">}</span><span class="s2">. </span><span class="si">{</span><span class="n">m</span><span class="p">[</span><span class="s1">'description'</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">movies</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">embeddings</span> <span class="o">=</span> <span class="n">batch_generate_embeddings</span><span class="p">(</span><span class="n">texts</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">32</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">movie</span><span class="p">,</span> <span class="n">embedding</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">movies</span><span class="p">,</span> <span class="n">embeddings</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">movie</span><span class="p">[</span><span class="s1">'embedding'</span><span class="p">]</span> <span class="o">=</span> <span class="n">embedding</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
</span></span></code></pre></div>
<h3 id="complete-example-product-recommendations" class="position-relative d-flex align-items-center group">
<span>Complete Example: Product Recommendations</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="complete-example-product-recommendations"
aria-haspopup="dialog"
aria-label="Share link: Complete Example: Product Recommendations">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># E-commerce product recommendation system</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Sample products</span>
</span></span><span class="line"><span class="cl"><span class="n">products</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="s2">"p1"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">:</span> <span class="s2">"Wireless Headphones"</span><span class="p">,</span> <span class="s2">"desc"</span><span class="p">:</span> <span class="s2">"Premium noise-cancelling wireless headphones with 30-hour battery"</span><span class="p">,</span> <span class="s2">"price"</span><span class="p">:</span> <span class="mi">299</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="s2">"p2"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">:</span> <span class="s2">"Bluetooth Speaker"</span><span class="p">,</span> <span class="s2">"desc"</span><span class="p">:</span> <span class="s2">"Portable waterproof Bluetooth speaker with deep bass"</span><span class="p">,</span> <span class="s2">"price"</span><span class="p">:</span> <span class="mi">89</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="s2">"p3"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">:</span> <span class="s2">"Smart Watch"</span><span class="p">,</span> <span class="s2">"desc"</span><span class="p">:</span> <span class="s2">"Fitness tracking smartwatch with heart rate monitor and GPS"</span><span class="p">,</span> <span class="s2">"price"</span><span class="p">:</span> <span class="mi">399</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="s2">"p4"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">:</span> <span class="s2">"Running Shoes"</span><span class="p">,</span> <span class="s2">"desc"</span><span class="p">:</span> <span class="s2">"Lightweight running shoes with advanced cushioning technology"</span><span class="p">,</span> <span class="s2">"price"</span><span class="p">:</span> <span class="mi">120</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="s2">"p5"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">:</span> <span class="s2">"Fitness Tracker"</span><span class="p">,</span> <span class="s2">"desc"</span><span class="p">:</span> <span class="s2">"Activity tracker with sleep monitoring and step counting"</span><span class="p">,</span> <span class="s2">"price"</span><span class="p">:</span> <span class="mi">79</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Generate and store embeddings</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"CREATE GRAPH ProductRecommendations; USE ProductRecommendations;"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">product</span> <span class="ow">in</span> <span class="n">products</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">product</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]</span><span class="si">}</span><span class="s2">. </span><span class="si">{</span><span class="n">product</span><span class="p">[</span><span class="s1">'desc'</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span>
</span></span><span class="line"><span class="cl"> <span class="n">embedding</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">text</span><span class="p">)</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (:Product {
</span></span></span><span class="line"><span class="cl"><span class="s2"> id: $id,
</span></span></span><span class="line"><span class="cl"><span class="s2"> name: $name,
</span></span></span><span class="line"><span class="cl"><span class="s2"> description: $desc,
</span></span></span><span class="line"><span class="cl"><span class="s2"> price: $price,
</span></span></span><span class="line"><span class="cl"><span class="s2"> embedding: $embedding
</span></span></span><span class="line"><span class="cl"><span class="s2"> })
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="o">**</span><span class="n">product</span><span class="p">,</span> <span class="s1">'embedding'</span><span class="p">:</span> <span class="n">embedding</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create index</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"CREATE INDEX product_emb_idx ON Product(embedding) USING vector"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># User query: "fitness gadget for running"</span>
</span></span><span class="line"><span class="cl"><span class="n">query</span> <span class="o">=</span> <span class="s2">"fitness gadget for running"</span>
</span></span><span class="line"><span class="cl"><span class="n">query_emb</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">query</span><span class="p">)</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (p:Product)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE vector_distance_cosine(p.embedding, $query_vec) < 0.7
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN p.name,
</span></span></span><span class="line"><span class="cl"><span class="s2"> p.price,
</span></span></span><span class="line"><span class="cl"><span class="s2"> vector_distance_cosine(p.embedding, $query_vec) AS relevance
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY relevance ASC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 3
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_emb</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Recommendations for: '</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">'"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">rows</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">name</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"p.name"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="n">price</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"p.price"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="n">relevance</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">"relevance"</span><span class="p">]</span><span class="o">.</span><span class="n">raw_value</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">. </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2"> - $</span><span class="si">{</span><span class="n">price</span><span class="si">}</span><span class="s2"> (score: </span><span class="si">{</span><span class="mi">1</span><span class="o">-</span><span class="n">relevance</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Expected output:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Recommendations for: 'fitness gadget for running'</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 1. Fitness Tracker - $79 (score: 0.85)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Smart Watch - $399 (score: 0.78)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 3. Running Shoes - $120 (score: 0.72)</span>
</span></span></code></pre></div>
<h3 id="troubleshooting" class="position-relative d-flex align-items-center group">
<span>Troubleshooting</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="troubleshooting"
aria-haspopup="dialog"
aria-label="Share link: Troubleshooting">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="index-not-being-used" class="position-relative d-flex align-items-center group">
<span>Index Not Being Used</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="index-not-being-used"
aria-haspopup="dialog"
aria-label="Share link: Index Not Being Used">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Problem</strong>: Queries slow despite having vector index</p>
<p><strong>Solutions</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 1. Verify index exists</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"SHOW INDEXES ON Movie"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Check index is ready</span>
</span></span><span class="line"><span class="cl"><span class="c1"># (Index builds asynchronously)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. Use EXPLAIN to verify</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> EXPLAIN
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE vector_distance_cosine(m.embedding, $vec) < 0.5
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Look for "IndexScan [movie_embedding_idx]"</span>
</span></span></code></pre></div>
<h4 id="out-of-memory" class="position-relative d-flex align-items-center group">
<span>Out of Memory</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="out-of-memory"
aria-haspopup="dialog"
aria-label="Share link: Out of Memory">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Problem</strong>: Large embeddings cause memory issues</p>
<p><strong>Solutions</strong>:</p>
<ul>
<li>Use smaller embedding models (384 dims vs 768 dims)</li>
<li>Reduce <code>ef_construction</code> and <code>m</code> parameters</li>
<li>Index only frequently searched items</li>
<li>Use dimensionality reduction (PCA)</li>
</ul>
<h4 id="poor-recall" class="position-relative d-flex align-items-center group">
<span>Poor Recall</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="poor-recall"
aria-haspopup="dialog"
aria-label="Share link: Poor Recall">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Problem</strong>: Missing relevant results</p>
<p><strong>Solutions</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Increase ef_search parameter</span>
</span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE INDEX better_recall_idx ON Movie(embedding) USING vector
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH </span><span class="si">{ef_search: 300}</span><span class="s2"> -- Higher = better recall
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Increase distance threshold</span>
</span></span><span class="line"><span class="cl"><span class="n">page</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (m:Movie)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE vector_distance_cosine(m.embedding, $query_vec) < 0.8 -- More lenient
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN m.title
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="p">{</span><span class="s1">'query_vec'</span><span class="p">:</span> <span class="n">query_embedding</span><span class="p">})</span>
</span></span></code></pre></div>
<h3 id="next-steps" class="position-relative d-flex align-items-center group">
<span>Next Steps</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="next-steps"
aria-haspopup="dialog"
aria-label="Share link: Next Steps">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li><a
href="/docs/analytics/real-time-analytics/"
>Real-Time Analytics</a>
- Stream embeddings with CDC</li>
<li><a
href="/docs/analytics/graph-algorithms/"
>Graph Algorithms</a>
- Combine vector search with graph traversal</li>
<li><a
href="/docs/performance/"
>Performance Tuning</a>
- Optimize large-scale vector search</li>
<li><a
href="/docs/data-types/"
>Data Types Reference</a>
- VectorF32 and VectorI32 types</li>
</ul>
<h3 id="quick-reference" class="position-relative d-flex align-items-center group">
<span>Quick Reference</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="quick-reference"
aria-haspopup="dialog"
aria-label="Share link: Quick Reference">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="distance-functions" class="position-relative d-flex align-items-center group">
<span>Distance Functions</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="distance-functions"
aria-haspopup="dialog"
aria-label="Share link: Distance Functions">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Cosine</span><span class="w"> </span><span class="py">distance</span><span class="w"> </span><span class="p">(</span><span class="py">0</span><span class="err">-</span><span class="py">2</span><span class="p">,</span><span class="w"> </span><span class="py">lower</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">more</span><span class="w"> </span><span class="py">similar</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">vector_distance_cosine</span><span class="p">(</span><span class="py">vec1</span><span class="p">,</span><span class="w"> </span><span class="py">vec2</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">L2</span><span class="w"> </span><span class="py">distance</span><span class="w"> </span><span class="p">(</span><span class="py">Euclidean</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">vector_distance_l2</span><span class="p">(</span><span class="py">vec1</span><span class="p">,</span><span class="w"> </span><span class="py">vec2</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Inner</span><span class="w"> </span><span class="py">product</span><span class="w"> </span><span class="p">(</span><span class="py">higher</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">more</span><span class="w"> </span><span class="py">similar</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">vector_inner_product</span><span class="p">(</span><span class="py">vec1</span><span class="p">,</span><span class="w"> </span><span class="py">vec2</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Manhattan</span><span class="w"> </span><span class="py">distance</span><span class="w"> </span><span class="p">(</span><span class="py">L1</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">vector_distance_l1</span><span class="p">(</span><span class="py">vec1</span><span class="p">,</span><span class="w"> </span><span class="py">vec2</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="index-commands" class="position-relative d-flex align-items-center group">
<span>Index Commands</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="index-commands"
aria-haspopup="dialog"
aria-label="Share link: Index Commands">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Create</span><span class="w"> </span><span class="py">vector</span><span class="w"> </span><span class="py">index</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">idx_name</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Label</span><span class="p">(</span><span class="py">property</span><span class="p">)</span><span class="w"> </span><span class="py">USING</span><span class="w"> </span><span class="py">vector</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Create</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">parameters</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">idx_name</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Label</span><span class="p">(</span><span class="py">property</span><span class="p">)</span><span class="w"> </span><span class="py">USING</span><span class="w"> </span><span class="py">vector</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="p">{</span><span class="py">m</span><span class="p">:</span><span class="w"> </span><span class="nc">16</span><span class="p">,</span><span class="w"> </span><span class="py">ef_construction</span><span class="p">:</span><span class="w"> </span><span class="nc">200</span><span class="p">,</span><span class="w"> </span><span class="py">ef_search</span><span class="p">:</span><span class="w"> </span><span class="nc">100</span><span class="p">}</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Drop</span><span class="w"> </span><span class="py">index</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DROP</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">idx_name</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Show</span><span class="w"> </span><span class="py">indexes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SHOW</span><span class="w"> </span><span class="py">INDEXES</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Label</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="python-helpers" class="position-relative d-flex align-items-center group">
<span>Python Helpers</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="python-helpers"
aria-haspopup="dialog"
aria-label="Share link: Python Helpers">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Normalize vector</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">normalize</span><span class="p">(</span><span class="n">vec</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">vec</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">vec</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Cosine similarity</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">cosine_sim</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">b</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># L2 distance</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">l2_dist</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">a</span> <span class="o">-</span> <span class="n">b</span><span class="p">)</span>
</span></span></code></pre></div><hr>
<p><strong>Tutorial Complete!</strong> You now understand vector similarity search in Geode.</p>
<p><strong>Next</strong>: <a
href="/docs/tutorials/transaction-patterns-tutorial/"
>Transaction Patterns Tutorial</a>
</p>
Vector Similarity Search Tutorial
Learn vector similarity search with Geode: generate embeddings, create HNSW indexes, and find semantically similar items with cosine and L2 distance