<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 -->
<p>Documentation tagged with <strong>BM25 Ranking Algorithm</strong> in the Geode graph database. BM25 (Best Matching 25) is a probabilistic ranking function used for text search and information retrieval, providing relevance scoring for keyword-based document searches.</p>
<h3 id="introduction-to-bm25" class="position-relative d-flex align-items-center group">
<span>Introduction to BM25</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="introduction-to-bm25"
aria-haspopup="dialog"
aria-label="Share link: Introduction to BM25">
<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 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>BM25 (Best Matching 25) is the gold standard ranking function for text search. Developed by Stephen Robertson and Karen Spärck Jones in the 1990s as part of the Okapi information retrieval system, BM25 has become the default ranking algorithm in search engines like Elasticsearch, Apache Solr, and Apache Lucene.</p>
<p>BM25 solves a fundamental question: given a search query and a collection of documents, which documents are most relevant? The algorithm computes a relevance score based on:</p>
<ul>
<li><strong>Term frequency</strong>: How often query terms appear in each document</li>
<li><strong>Inverse document frequency</strong>: How rare or common terms are across all documents</li>
<li><strong>Document length normalization</strong>: Penalizing long documents that contain many terms</li>
<li><strong>Saturation</strong>: Diminishing returns for repeated terms</li>
</ul>
<p>Unlike simple keyword matching (which is binary: match or no match), BM25 provides nuanced relevance scores that enable ranking search results by quality. This makes it invaluable for full-text search applications.</p>
<p>Geode implements BM25 for property text search, enabling powerful keyword-based search that complements semantic vector search (HNSW). You can combine BM25 text search with graph traversal for queries like “find documents about databases written by friends, ranked by relevance.”</p>
<h3 id="core-bm25-concepts" class="position-relative d-flex align-items-center group">
<span>Core BM25 Concepts</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="core-bm25-concepts"
aria-haspopup="dialog"
aria-label="Share link: Core BM25 Concepts">
<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="the-bm25-formula" class="position-relative d-flex align-items-center group">
<span>The BM25 Formula</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="the-bm25-formula"
aria-haspopup="dialog"
aria-label="Share link: The BM25 Formula">
<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>BM25 computes a relevance score for document D given query Q:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">score(D, Q) = Σ IDF(qi) * (f(qi, D) * (k1 + 1)) / (f(qi, D) + k1 * (1 - b + b * |D| / avgdl))
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Where:
</span></span><span class="line"><span class="cl">- qi: Each term in query Q
</span></span><span class="line"><span class="cl">- f(qi, D): Frequency of qi in document D
</span></span><span class="line"><span class="cl">- |D|: Length of document D (in tokens)
</span></span><span class="line"><span class="cl">- avgdl: Average document length in collection
</span></span><span class="line"><span class="cl">- k1: Term frequency saturation parameter (typically 1.2-2.0)
</span></span><span class="line"><span class="cl">- b: Length normalization parameter (typically 0.75)
</span></span><span class="line"><span class="cl">- IDF(qi): Inverse document frequency of qi
</span></span></code></pre></div>
<h4 id="term-frequency-tf" class="position-relative d-flex align-items-center group">
<span>Term Frequency (TF)</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="term-frequency-tf"
aria-haspopup="dialog"
aria-label="Share link: Term Frequency (TF)">
<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>Term frequency measures how often a query term appears in a document. BM25 uses a saturating function—the first few occurrences of a term matter much more than later ones:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">TF Impact:
</span></span><span class="line"><span class="cl">1 occurrence: High impact
</span></span><span class="line"><span class="cl">2 occurrences: Medium impact
</span></span><span class="line"><span class="cl">10 occurrences: Marginal additional impact
</span></span><span class="line"><span class="cl">100 occurrences: Almost no additional impact
</span></span></code></pre></div><p>This saturation prevents keyword stuffing from artificially inflating relevance.</p>
<h4 id="inverse-document-frequency-idf" class="position-relative d-flex align-items-center group">
<span>Inverse Document Frequency (IDF)</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="inverse-document-frequency-idf"
aria-haspopup="dialog"
aria-label="Share link: Inverse Document Frequency (IDF)">
<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>IDF measures how rare or common a term is across the entire document collection:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">IDF(term) = log((N - n(term) + 0.5) / (n(term) + 0.5))
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Where:
</span></span><span class="line"><span class="cl">- N: Total number of documents
</span></span><span class="line"><span class="cl">- n(term): Number of documents containing term
</span></span></code></pre></div><p>Common terms (like “the”, “and”) have low IDF and contribute little to relevance. Rare terms have high IDF and strongly indicate relevance.</p>
<p>Examples:</p>
<ul>
<li>“the” appears in 1M of 1M docs → IDF ≈ 0</li>
<li>“database” appears in 10K of 1M docs → IDF ≈ 4.6</li>
<li>“geode” appears in 100 of 1M docs → IDF ≈ 9.2</li>
</ul>
<h4 id="length-normalization" class="position-relative d-flex align-items-center group">
<span>Length Normalization</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="length-normalization"
aria-haspopup="dialog"
aria-label="Share link: Length Normalization">
<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>Longer documents tend to contain more terms by chance. BM25 penalizes long documents to avoid bias:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Length penalty = 1 - b + b * |D| / avgdl
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Where:
</span></span><span class="line"><span class="cl">- b = 0: No length normalization
</span></span><span class="line"><span class="cl">- b = 1: Full length normalization
</span></span><span class="line"><span class="cl">- b = 0.75: Balanced (typical)
</span></span></code></pre></div><p>A document twice as long as average receives a moderate penalty.</p>
<h4 id="parameter-tuning" class="position-relative d-flex align-items-center group">
<span>Parameter 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="parameter-tuning"
aria-haspopup="dialog"
aria-label="Share link: Parameter 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><p>BM25 has two main parameters:</p>
<p><strong>k1 (term frequency saturation)</strong>:</p>
<ul>
<li>Low (0.5-1.0): Aggressive saturation, repeated terms matter less</li>
<li>Medium (1.2-1.5): Balanced (typical default: 1.2)</li>
<li>High (2.0-3.0): Weak saturation, repeated terms matter more</li>
</ul>
<p><strong>b (length normalization)</strong>:</p>
<ul>
<li>Low (0.0-0.5): Weak length penalty</li>
<li>Medium (0.75): Balanced (typical default)</li>
<li>High (0.9-1.0): Strong length penalty</li>
</ul>
<h3 id="how-bm25-works-in-geode" class="position-relative d-flex align-items-center group">
<span>How BM25 Works in 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="how-bm25-works-in-geode"
aria-haspopup="dialog"
aria-label="Share link: How BM25 Works in 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>
</h3>
<h4 id="creating-full-text-indexes" class="position-relative d-flex align-items-center group">
<span>Creating Full-Text Indexes</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="creating-full-text-indexes"
aria-haspopup="dialog"
aria-label="Share link: Creating Full-Text Indexes">
<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>Enable BM25 ranking by creating full-text indexes:</p>
<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">full</span><span class="err">-</span><span class="py">text</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">document</span><span class="w"> </span><span class="py">content</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">document_content</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">standard</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Tokenization</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">stemming</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">k1</span><span class="p">:</span><span class="w"> </span><span class="nc">1</span><span class="mf">.2</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Term</span><span class="w"> </span><span class="py">frequency</span><span class="w"> </span><span class="py">saturation</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">b</span><span class="p">:</span><span class="w"> </span><span class="nc">0</span><span class="mf">.75</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Length</span><span class="w"> </span><span class="py">normalization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p>Options:</p>
<ul>
<li><strong>analyzer</strong>: Text processing (standard, english, multilingual, custom)</li>
<li><strong>k1</strong>: Term frequency saturation parameter</li>
<li><strong>b</strong>: Length normalization parameter</li>
<li><strong>stopwords</strong>: Words to ignore (the, and, or, etc.)</li>
<li><strong>stemming</strong>: Reduce words to roots (running → run)</li>
</ul>
<h4 id="full-text-search-queries" class="position-relative d-flex align-items-center group">
<span>Full-Text Search Queries</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="full-text-search-queries"
aria-haspopup="dialog"
aria-label="Share link: Full-Text Search Queries">
<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>Search using the text index:</p>
<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">BM25</span><span class="err">-</span><span class="py">ranked</span><span class="w"> </span><span class="py">full</span><span class="err">-</span><span class="py">text</span><span class="w"> </span><span class="py">search</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">graph</span><span class="w"> </span><span class="py">database</span><span class="w"> </span><span class="py">performance</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">author</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relevance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">relevance</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">20</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">Or</span><span class="w"> </span><span class="py">using</span><span class="w"> </span><span class="py">CALL</span><span class="w"> </span><span class="py">syntax</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">fulltext</span><span class="err">.</span><span class="py">search</span><span class="p">({</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">index</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">document_content</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">query</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">graph</span><span class="w"> </span><span class="nc">database</span><span class="w"> </span><span class="py">performance</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">limit</span><span class="p">:</span><span class="w"> </span><span class="nc">20</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">YIELD</span><span class="w"> </span><span class="py">node</span><span class="p">,</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">node</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="boolean-queries" class="position-relative d-flex align-items-center group">
<span>Boolean Queries</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="boolean-queries"
aria-haspopup="dialog"
aria-label="Share link: Boolean Queries">
<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>Combine terms with Boolean operators:</p>
<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">Must</span><span class="w"> </span><span class="py">contain</span><span class="w"> </span><span class="s">"graph"</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="s">"database"</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'+</span><span class="py">graph</span><span class="w"> </span><span class="err">+</span><span class="py">database</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</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">Must</span><span class="w"> </span><span class="py">contain</span><span class="w"> </span><span class="s">"graph"</span><span class="p">,</span><span class="w"> </span><span class="py">should</span><span class="w"> </span><span class="py">contain</span><span class="w"> </span><span class="s">"database"</span><span class="w"> </span><span class="p">(</span><span class="py">boosts</span><span class="w"> </span><span class="py">score</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'+</span><span class="py">graph</span><span class="w"> </span><span class="py">database</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</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">Contains</span><span class="w"> </span><span class="s">"graph"</span><span class="w"> </span><span class="py">but</span><span class="w"> </span><span class="py">not</span><span class="w"> </span><span class="s">"neo4j"</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">graph</span><span class="w"> </span><span class="err">-</span><span class="py">neo4j</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="phrase-queries" class="position-relative d-flex align-items-center group">
<span>Phrase Queries</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="phrase-queries"
aria-haspopup="dialog"
aria-label="Share link: Phrase Queries">
<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>Search for exact phrases:</p>
<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">Exact</span><span class="w"> </span><span class="py">phrase</span><span class="w"> </span><span class="py">match</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="s">"graph database"</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</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">Proximity</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="p">(</span><span class="py">words</span><span class="w"> </span><span class="py">within</span><span class="w"> </span><span class="py">5</span><span class="w"> </span><span class="py">tokens</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="s">"graph database"</span><span class="err">~</span><span class="py">5</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="combining-with-graph-traversal" class="position-relative d-flex align-items-center group">
<span>Combining with Graph Traversal</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="combining-with-graph-traversal"
aria-haspopup="dialog"
aria-label="Share link: Combining with Graph Traversal">
<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>The power of BM25 in a graph database:</p>
<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">Find</span><span class="w"> </span><span class="py">relevant</span><span class="w"> </span><span class="py">documents</span><span class="w"> </span><span class="py">written</span><span class="w"> </span><span class="py">by</span><span class="w"> </span><span class="py">friends</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">me</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$userId</span><span class="p">})</span><span class="err">-</span><span class="p">[:</span><span class="nc">FRIEND</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="nc">friend</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">-</span><span class="p">[:</span><span class="nc">AUTHORED</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">doc</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">author</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">doc</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relevance</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">DISTINCT</span><span class="w"> </span><span class="py">friend</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">friend_author_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">relevance</span><span class="w"> </span><span class="py">DESC</span><span class="p">,</span><span class="w"> </span><span class="py">friend_author_count</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">10</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">Search</span><span class="w"> </span><span class="py">within</span><span class="w"> </span><span class="py">a</span><span class="w"> </span><span class="py">specific</span><span class="w"> </span><span class="py">graph</span><span class="w"> </span><span class="py">context</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">category</span><span class="p">:</span><span class="nc">Category</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Technology</span><span class="err">'</span><span class="p">})</span><span class="err"><-</span><span class="p">[:</span><span class="nc">IN_CATEGORY</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">doc</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">machine</span><span class="w"> </span><span class="py">learning</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">publish_date</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">date</span><span class="p">(</span><span class="err">'</span><span class="py">2024</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">doc</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">20</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="use-cases" class="position-relative d-flex align-items-center group">
<span>Use Cases</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="use-cases"
aria-haspopup="dialog"
aria-label="Share link: Use Cases">
<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="document-search" class="position-relative d-flex align-items-center group">
<span>Document 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="document-search"
aria-haspopup="dialog"
aria-label="Share link: Document 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><p>Classic full-text search:</p>
<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">Search</span><span class="w"> </span><span class="py">knowledge</span><span class="w"> </span><span class="py">base</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">doc</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$user_query</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">summary</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">doc</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relevance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">relevance</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">50</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="e-commerce-product-search" class="position-relative d-flex align-items-center group">
<span>E-Commerce Product 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="e-commerce-product-search"
aria-haspopup="dialog"
aria-label="Share link: E-Commerce Product 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><p>Find relevant products:</p>
<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">Product</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">metadata</span><span class="w"> </span><span class="py">filtering</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">product</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">product</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">description</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">price</span><span class="w"> </span><span class="py">BETWEEN</span><span class="w"> </span><span class="nv">$min_price</span><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="nv">$max_price</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">in_stock</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">price</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">product</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relevance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">relevance</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">20</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="log-and-event-search" class="position-relative d-flex align-items-center group">
<span>Log and Event 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="log-and-event-search"
aria-haspopup="dialog"
aria-label="Share link: Log and Event 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><p>Search through logs:</p>
<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">Find</span><span class="w"> </span><span class="py">relevant</span><span class="w"> </span><span class="py">log</span><span class="w"> </span><span class="py">entries</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">log</span><span class="p">:</span><span class="nc">LogEntry</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">log</span><span class="err">.</span><span class="py">message</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">error</span><span class="w"> </span><span class="py">timeout</span><span class="w"> </span><span class="py">connection</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">log</span><span class="err">.</span><span class="py">timestamp</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">datetime</span><span class="p">()</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">duration</span><span class="p">(</span><span class="err">'</span><span class="py">P1D</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">log</span><span class="err">.</span><span class="py">severity</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="p">[</span><span class="err">'</span><span class="py">ERROR</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">FATAL</span><span class="err">'</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">log</span><span class="err">.</span><span class="py">timestamp</span><span class="p">,</span><span class="w"> </span><span class="py">log</span><span class="err">.</span><span class="py">message</span><span class="p">,</span><span class="w"> </span><span class="py">log</span><span class="err">.</span><span class="py">service</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">log</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="p">,</span><span class="w"> </span><span class="py">log</span><span class="err">.</span><span class="py">timestamp</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">100</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="hybrid-search-bm25--vector-search" class="position-relative d-flex align-items-center group">
<span>Hybrid Search (BM25 + Vector 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="hybrid-search-bm25--vector-search"
aria-haspopup="dialog"
aria-label="Share link: Hybrid Search (BM25 &#43; Vector 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><p>Combine keyword and semantic search:</p>
<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">Hybrid</span><span class="w"> </span><span class="py">search</span><span class="p">:</span><span class="w"> </span><span class="nc">BM25</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">HNSW</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">doc</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$keyword_query</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">vector_similarity</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">embedding</span><span class="p">,</span><span class="w"> </span><span class="nv">$query_embedding</span><span class="p">)</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="mf">.7</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="py">doc</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">doc</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">bm25_score</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_similarity</span><span class="p">(</span><span class="py">doc</span><span class="err">.</span><span class="py">embedding</span><span class="p">,</span><span class="w"> </span><span class="nv">$query_embedding</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">vector_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">doc</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">bm25_score</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_score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="py">0</span><span class="mf">.6</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">bm25_score</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">0</span><span class="mf">.4</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">vector_score</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">combined_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">combined_score</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">20</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p>This hybrid approach leverages both keyword matching (BM25) and semantic understanding (vectors).</p>
<h3 id="best-practices" class="position-relative d-flex align-items-center group">
<span>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="best-practices"
aria-haspopup="dialog"
aria-label="Share link: 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="index-configuration" class="position-relative d-flex align-items-center group">
<span>Index Configuration</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-configuration"
aria-haspopup="dialog"
aria-label="Share link: Index Configuration">
<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>Choose the right analyzer</strong>:</p>
<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">English</span><span class="w"> </span><span class="py">text</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">stemming</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">docs_en</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">english</span><span class="err">'</span><span class="p">}</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">running</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">run</span><span class="p">,</span><span class="w"> </span><span class="py">databases</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">database</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">Multilingual</span><span class="w"> </span><span class="py">support</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">docs_multi</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">multilingual</span><span class="err">'</span><span class="p">}</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Detects</span><span class="w"> </span><span class="py">language</span><span class="w"> </span><span class="py">automatically</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">Code</span><span class="err">/</span><span class="py">technical</span><span class="w"> </span><span class="py">content</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">code</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Code</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">keyword</span><span class="err">'</span><span class="p">}</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">No</span><span class="w"> </span><span class="py">stemming</span><span class="p">,</span><span class="w"> </span><span class="py">preserve</span><span class="w"> </span><span class="py">exact</span><span class="w"> </span><span class="py">terms</span><span class="w">
</span></span></span></code></pre></div><p><strong>Configure stopwords</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">docs</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">stopwords</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">'</span><span class="nc">the</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">a</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">an</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">and</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">or</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">but</span><span class="err">'</span><span class="p">]</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Custom</span><span class="w"> </span><span class="py">stopword</span><span class="w"> </span><span class="py">list</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="query-optimization" class="position-relative d-flex align-items-center group">
<span>Query 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="query-optimization"
aria-haspopup="dialog"
aria-label="Share link: Query 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>
</h4><p><strong>Use specific terms</strong>:</p>
<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">Poor</span><span class="p">:</span><span class="w"> </span><span class="nc">Too</span><span class="w"> </span><span class="py">generic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">data</span><span class="err">'</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">Better</span><span class="p">:</span><span class="w"> </span><span class="nc">Specific</span><span class="w"> </span><span class="py">terms</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">graph</span><span class="w"> </span><span class="py">database</span><span class="w"> </span><span class="py">ACID</span><span class="w"> </span><span class="py">transactions</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p><strong>Combine with filters</strong>:</p>
<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">Efficient</span><span class="p">:</span><span class="w"> </span><span class="nc">Filter</span><span class="w"> </span><span class="py">before</span><span class="w"> </span><span class="py">expensive</span><span class="w"> </span><span class="py">text</span><span class="w"> </span><span class="py">search</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">category</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="py">technical</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">publish_date</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">date</span><span class="p">(</span><span class="err">'</span><span class="py">2024</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Tune parameters for your data</strong>:</p>
<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">Short</span><span class="w"> </span><span class="py">documents</span><span class="w"> </span><span class="p">(</span><span class="py">tweets</span><span class="p">,</span><span class="w"> </span><span class="py">titles</span><span class="p">):</span><span class="w"> </span><span class="nc">Reduce</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="py">penalty</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">tweets</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">t</span><span class="p">:</span><span class="nc">Tweet</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">t</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="py">k1</span><span class="p">:</span><span class="w"> </span><span class="nc">1</span><span class="mf">.2</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">:</span><span class="w"> </span><span class="nc">0</span><span class="mf">.5</span><span class="p">}</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Weak</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="py">normalization</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">Long</span><span class="w"> </span><span class="py">documents</span><span class="w"> </span><span class="p">(</span><span class="py">articles</span><span class="p">,</span><span class="w"> </span><span class="py">books</span><span class="p">):</span><span class="w"> </span><span class="nc">Increase</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="py">penalty</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">articles</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Article</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="py">k1</span><span class="p">:</span><span class="w"> </span><span class="nc">1</span><span class="mf">.2</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">:</span><span class="w"> </span><span class="nc">0</span><span class="mf">.9</span><span class="p">}</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Strong</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="py">normalization</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="relevance-tuning" class="position-relative d-flex align-items-center group">
<span>Relevance 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="relevance-tuning"
aria-haspopup="dialog"
aria-label="Share link: Relevance 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><p><strong>Field weighting</strong>:</p>
<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">Weight</span><span class="w"> </span><span class="py">title</span><span class="w"> </span><span class="py">matches</span><span class="w"> </span><span class="py">higher</span><span class="w"> </span><span class="py">than</span><span class="w"> </span><span class="py">content</span><span class="w"> </span><span class="py">matches</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</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="py">d</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">CASE</span><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span><span class="py">3</span><span class="mf">.0</span><span class="w"> </span><span class="py">ELSE</span><span class="w"> </span><span class="py">0</span><span class="mf">.0</span><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">title_score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">CASE</span><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="py">ELSE</span><span class="w"> </span><span class="py">0</span><span class="mf">.0</span><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">content_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">title_score</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">content_score</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="py">title_score</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">content_score</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Query-time boosting</strong>:</p>
<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">Boost</span><span class="w"> </span><span class="py">recent</span><span class="w"> </span><span class="py">documents</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</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="py">d</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">base_score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="py">datetime</span><span class="p">()</span><span class="err">.</span><span class="py">epochSeconds</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">publish_date</span><span class="err">.</span><span class="py">epochSeconds</span><span class="p">)</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="p">(</span><span class="py">86400</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">365</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">age_years</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">base_score</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="py">base_score</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="p">(</span><span class="py">1</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">0</span><span class="mf">.1</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">age_years</span><span class="p">))</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">adjusted_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">adjusted_score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="performance-considerations" class="position-relative d-flex align-items-center group">
<span>Performance Considerations</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="performance-considerations"
aria-haspopup="dialog"
aria-label="Share link: Performance Considerations">
<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-size" class="position-relative d-flex align-items-center group">
<span>Index Size</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-size"
aria-haspopup="dialog"
aria-label="Share link: Index Size">
<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>Full-text indexes require additional storage:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Index size ≈ 30-50% of original text size
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Example:
</span></span><span class="line"><span class="cl">- 1M documents, 5KB average
</span></span><span class="line"><span class="cl">- Total text: 5GB
</span></span><span class="line"><span class="cl">- Index size: 1.5-2.5GB
</span></span></code></pre></div>
<h4 id="query-performance" class="position-relative d-flex align-items-center group">
<span>Query Performance</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="query-performance"
aria-haspopup="dialog"
aria-label="Share link: Query Performance">
<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>Typical performance characteristics:</p>
<ul>
<li><strong>Simple queries</strong>: 1-10ms for millions of documents</li>
<li><strong>Complex Boolean queries</strong>: 10-50ms</li>
<li><strong>Combined graph + text</strong>: 50-500ms depending on graph complexity</li>
</ul>
<h4 id="optimization-tips" class="position-relative d-flex align-items-center group">
<span>Optimization Tips</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="optimization-tips"
aria-haspopup="dialog"
aria-label="Share link: Optimization Tips">
<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><ol>
<li><strong>Limit result set</strong>: Always use LIMIT to cap results</li>
<li><strong>Pre-filter</strong>: Use property filters before text search</li>
<li><strong>Cache common queries</strong>: Cache frequent query results</li>
<li><strong>Partition large collections</strong>: Split by category, date, etc.</li>
</ol>
<h3 id="monitoring" class="position-relative d-flex align-items-center group">
<span>Monitoring</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="monitoring"
aria-haspopup="dialog"
aria-label="Share link: Monitoring">
<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-statistics" class="position-relative d-flex align-items-center group">
<span>Index Statistics</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-statistics"
aria-haspopup="dialog"
aria-label="Share link: Index Statistics">
<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">Check</span><span class="w"> </span><span class="py">index</span><span class="w"> </span><span class="py">statistics</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">fulltext</span><span class="err">.</span><span class="py">index</span><span class="err">.</span><span class="py">stats</span><span class="p">(</span><span class="err">'</span><span class="py">document_content</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">YIELD</span><span class="w"> </span><span class="py">documents</span><span class="p">,</span><span class="w"> </span><span class="py">terms</span><span class="p">,</span><span class="w"> </span><span class="py">size_mb</span><span class="p">,</span><span class="w"> </span><span class="py">avg_doc_length</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">documents</span><span class="p">,</span><span class="w"> </span><span class="py">terms</span><span class="p">,</span><span class="w"> </span><span class="py">size_mb</span><span class="p">,</span><span class="w"> </span><span class="py">avg_doc_length</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="query-performance-1" class="position-relative d-flex align-items-center group">
<span>Query Performance</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="query-performance-1"
aria-haspopup="dialog"
aria-label="Share link: Query Performance">
<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">Profile</span><span class="w"> </span><span class="py">text</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="kd">query</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">PROFILE</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">20</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="related-topics" class="position-relative d-flex align-items-center group">
<span>Related Topics</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="related-topics"
aria-haspopup="dialog"
aria-label="Share link: Related Topics">
<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="/tags/search/"
>Search</a>
- General search capabilities</li>
<li><a
href="/tags/text/"
>Text</a>
- Text processing features</li>
<li><a
href="/tags/indexing/"
>Indexing</a>
- Index management</li>
<li><a
href="/tags/query-optimization/"
>Query Optimization</a>
- Performance tuning</li>
</ul>
<h3 id="further-reading" class="position-relative d-flex align-items-center group">
<span>Further Reading</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="further-reading"
aria-haspopup="dialog"
aria-label="Share link: Further Reading">
<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/query/full-text-search/"
>Full-Text Search Guide</a>
- Complete BM25 documentation</li>
<li><a
href="/docs/tutorials/vector-search-tutorial/"
>Vector Search Tutorial</a>
- Combining BM25 and vectors</li>
<li><a
href="/docs/query/performance-tuning/"
>Performance Tuning</a>
- Performance best practices</li>
</ul>
<p>Geode’s BM25 implementation provides powerful keyword-based search that integrates seamlessly with graph traversal, enabling rich text search applications combined with relationship-based filtering and ranking.</p>
<h3 id="advanced-bm25-techniques" class="position-relative d-flex align-items-center group">
<span>Advanced BM25 Techniques</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="advanced-bm25-techniques"
aria-haspopup="dialog"
aria-label="Share link: Advanced BM25 Techniques">
<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="bm25-improved-variant" class="position-relative d-flex align-items-center group">
<span>BM25+ (Improved Variant)</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="bm25-improved-variant"
aria-haspopup="dialog"
aria-label="Share link: BM25&#43; (Improved Variant)">
<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>BM25+ adds a delta parameter to prevent negative IDF values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">BM25+(D, Q) = Σ IDF(qi) × ((k1 + 1) × f(qi, D)) / (k1 × (1 - b + b × |D| / avgdl) + f(qi, D)) + δ
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Where δ = typically 1.0
</span></span></code></pre></div><p><strong>Advantages</strong>:</p>
<ul>
<li>Never penalizes term presence</li>
<li>Better performance on verbose queries</li>
<li>More robust to long documents</li>
</ul>
<h4 id="bm25f-field-weighted" class="position-relative d-flex align-items-center group">
<span>BM25F (Field-Weighted)</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="bm25f-field-weighted"
aria-haspopup="dialog"
aria-label="Share link: BM25F (Field-Weighted)">
<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>Weight different document fields separately:</p>
<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">BM25F</span><span class="p">:</span><span class="w"> </span><span class="nc">weighted</span><span class="w"> </span><span class="py">fields</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</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="py">d</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">title_score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">content_score</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">abstract</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">abstract_score</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="py">d</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">0</span><span class="mf">.5</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">title_score</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Title</span><span class="w"> </span><span class="py">boost</span><span class="p">:</span><span class="w"> </span><span class="nc">2x</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">0</span><span class="mf">.3</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">abstract_score</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Abstract</span><span class="w"> </span><span class="py">boost</span><span class="p">:</span><span class="w"> </span><span class="nc">1</span><span class="mf">.5</span><span class="py">x</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">0</span><span class="mf">.2</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">content_score</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Content</span><span class="p">:</span><span class="w"> </span><span class="nc">baseline</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">weighted_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">weighted_score</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">doc_id</span><span class="p">,</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">weighted_score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">weighted_score</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">20</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="query-expansion-and-relevance-feedback" class="position-relative d-flex align-items-center group">
<span>Query Expansion and Relevance Feedback</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="query-expansion-and-relevance-feedback"
aria-haspopup="dialog"
aria-label="Share link: Query Expansion and Relevance Feedback">
<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="pseudo-relevance-feedback" class="position-relative d-flex align-items-center group">
<span>Pseudo-Relevance Feedback</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="pseudo-relevance-feedback"
aria-haspopup="dialog"
aria-label="Share link: Pseudo-Relevance Feedback">
<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>Expand query using top results:</p>
<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">Stage</span><span class="w"> </span><span class="py">1</span><span class="p">:</span><span class="w"> </span><span class="nc">Initial</span><span class="w"> </span><span class="py">retrieval</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">fulltext</span><span class="err">.</span><span class="py">search</span><span class="p">({</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">index</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">documents</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">query</span><span class="p">:</span><span class="w"> </span><span class="nv">$original_query</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nc">limit</span><span class="p">:</span><span class="w"> </span><span class="nc">10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">YIELD</span><span class="w"> </span><span class="py">node</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">top_doc</span><span class="p">,</span><span class="w"> </span><span class="py">score</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">Stage</span><span class="w"> </span><span class="py">2</span><span class="p">:</span><span class="w"> </span><span class="nc">Extract</span><span class="w"> </span><span class="py">expansion</span><span class="w"> </span><span class="py">terms</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="py">top_doc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">top_doc</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">HAS_TERM</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">term</span><span class="p">:</span><span class="nc">Term</span><span class="p">)</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="py">term</span><span class="p">,</span><span class="w"> </span><span class="py">SUM</span><span class="p">(</span><span class="py">term</span><span class="err">.</span><span class="py">tfidf_score</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">term_importance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">term_importance</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">5</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="py">COLLECT</span><span class="p">(</span><span class="py">term</span><span class="err">.</span><span class="py">text</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">expansion_terms</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">Stage</span><span class="w"> </span><span class="py">3</span><span class="p">:</span><span class="w"> </span><span class="nc">Expanded</span><span class="w"> </span><span class="kd">query</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">WITH</span><span class="w"> </span><span class="nv">$original_query</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="err">'</span><span class="w"> </span><span class="err">'</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">join</span><span class="p">(</span><span class="py">expansion_terms</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="w"> </span><span class="err">'</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">expanded_query</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">fulltext</span><span class="err">.</span><span class="py">search</span><span class="p">({</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">index</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">documents</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">query</span><span class="p">:</span><span class="w"> </span><span class="nc">expanded_query</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nc">limit</span><span class="p">:</span><span class="w"> </span><span class="nc">50</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">YIELD</span><span class="w"> </span><span class="py">node</span><span class="p">,</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">node</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="query-relaxation" class="position-relative d-flex align-items-center group">
<span>Query Relaxation</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="query-relaxation"
aria-haspopup="dialog"
aria-label="Share link: Query Relaxation">
<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>Progressively relax boolean constraints:</p>
<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">Strict</span><span class="p">:</span><span class="w"> </span><span class="nc">All</span><span class="w"> </span><span class="py">terms</span><span class="w"> </span><span class="py">required</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'+</span><span class="py">term1</span><span class="w"> </span><span class="err">+</span><span class="py">term2</span><span class="w"> </span><span class="err">+</span><span class="py">term3</span><span class="err">'</span><span class="p">)</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="py">COUNT</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">strict_count</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">Relaxed</span><span class="p">:</span><span class="w"> </span><span class="nc">At</span><span class="w"> </span><span class="py">least</span><span class="w"> </span><span class="py">2</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">3</span><span class="w"> </span><span class="py">terms</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">strict_count</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">term1</span><span class="w"> </span><span class="py">term2</span><span class="w"> </span><span class="py">term3</span><span class="err">'</span><span class="p">)</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="py">d</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="mf">.5</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Higher</span><span class="w"> </span><span class="py">threshold</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">relaxed</span><span class="w"> </span><span class="kd">query</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="text-processing-and-analyzers" class="position-relative d-flex align-items-center group">
<span>Text Processing and Analyzers</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="text-processing-and-analyzers"
aria-haspopup="dialog"
aria-label="Share link: Text Processing and Analyzers">
<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="language-specific-analyzers" class="position-relative d-flex align-items-center group">
<span>Language-Specific Analyzers</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="language-specific-analyzers"
aria-haspopup="dialog"
aria-label="Share link: Language-Specific Analyzers">
<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">English</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">stemming</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">stopword</span><span class="w"> </span><span class="py">removal</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">docs_en</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">english</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">stopwords</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">'</span><span class="nc">the</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">a</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">an</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">and</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">or</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">but</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">in</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="kd">on</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">at</span><span class="err">'</span><span class="p">],</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">stemmer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">porter</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">k1</span><span class="p">:</span><span class="w"> </span><span class="nc">1</span><span class="mf">.2</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">b</span><span class="p">:</span><span class="w"> </span><span class="nc">0</span><span class="mf">.75</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></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">German</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">compound</span><span class="w"> </span><span class="py">word</span><span class="w"> </span><span class="py">handling</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">docs_de</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">german</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">stemmer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">snowball_german</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">compound_splitting</span><span class="p">:</span><span class="w"> </span><span class="nc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></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">Multi</span><span class="err">-</span><span class="py">language</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">automatic</span><span class="w"> </span><span class="py">detection</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">docs_multi</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">icu</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Unicode</span><span class="err">-</span><span class="py">aware</span><span class="w"> </span><span class="py">tokenization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">language_detection</span><span class="p">:</span><span class="w"> </span><span class="nc">true</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">k1</span><span class="p">:</span><span class="w"> </span><span class="nc">1</span><span class="mf">.5</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">b</span><span class="p">:</span><span class="w"> </span><span class="nc">0</span><span class="mf">.75</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="custom-analyzers" class="position-relative d-flex align-items-center group">
<span>Custom Analyzers</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="custom-analyzers"
aria-haspopup="dialog"
aria-label="Share link: Custom Analyzers">
<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">Code</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="py">analyzer</span><span class="w"> </span><span class="p">(</span><span class="py">no</span><span class="w"> </span><span class="py">stemming</span><span class="p">,</span><span class="w"> </span><span class="py">preserve</span><span class="w"> </span><span class="py">case</span><span class="p">)</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">code_search</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Code</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">c</span><span class="err">.</span><span class="py">source</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">code</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">tokenizer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">whitespace</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">filters</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">'</span><span class="nc">lowercase</span><span class="err">'</span><span class="p">],</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">preserve_original</span><span class="p">:</span><span class="w"> </span><span class="nc">true</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">k1</span><span class="p">:</span><span class="w"> </span><span class="nc">1</span><span class="mf">.2</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">b</span><span class="p">:</span><span class="w"> </span><span class="nc">0</span><span class="mf">.0</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">No</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="py">normalization</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">code</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></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">Product</span><span class="w"> </span><span class="py">SKU</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="p">(</span><span class="py">exact</span><span class="w"> </span><span class="py">matching</span><span class="p">)</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">product_sku</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">sku</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">keyword</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">No</span><span class="w"> </span><span class="py">tokenization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">case_sensitive</span><span class="p">:</span><span class="w"> </span><span class="nc">true</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">k1</span><span class="p">:</span><span class="w"> </span><span class="nc">2</span><span class="mf">.0</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Higher</span><span class="w"> </span><span class="py">term</span><span class="w"> </span><span class="py">frequency</span><span class="w"> </span><span class="py">boost</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="performance-optimization" class="position-relative d-flex align-items-center group">
<span>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="performance-optimization"
aria-haspopup="dialog"
aria-label="Share link: 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-sharding" class="position-relative d-flex align-items-center group">
<span>Index Sharding</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-sharding"
aria-haspopup="dialog"
aria-label="Share link: Index Sharding">
<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>Partition large indexes:</p>
<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">date</span><span class="err">-</span><span class="py">partitioned</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">CREATE</span><span class="w"> </span><span class="py">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">docs_2024</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">publish_date</span><span class="w"> </span><span class="err">></span><span class="p">=</span><span class="w"> </span><span class="py">date</span><span class="p">(</span><span class="err">'</span><span class="py">2024</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">english</span><span class="err">'</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="py">CREATE</span><span class="w"> </span><span class="py">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">docs_2023</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">publish_date</span><span class="w"> </span><span class="err">></span><span class="p">=</span><span class="w"> </span><span class="py">date</span><span class="p">(</span><span class="err">'</span><span class="py">2023</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">publish_date</span><span class="w"> </span><span class="err"><</span><span class="w"> </span><span class="py">date</span><span class="p">(</span><span class="err">'</span><span class="py">2024</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="py">analyzer</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">english</span><span class="err">'</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">Query</span><span class="w"> </span><span class="py">specific</span><span class="w"> </span><span class="py">partition</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">publish_date</span><span class="w"> </span><span class="err">></span><span class="p">=</span><span class="w"> </span><span class="py">date</span><span class="p">(</span><span class="err">'</span><span class="py">2024</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01</span><span class="err">'</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">d</span><span class="err">.</span><span class="py">title</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="caching-strategies" class="position-relative d-flex align-items-center group">
<span>Caching Strategies</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="caching-strategies"
aria-haspopup="dialog"
aria-label="Share link: Caching Strategies">
<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"># Cache frequent query results</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">lru_cache</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@lru_cache</span><span class="p">(</span><span class="n">maxsize</span><span class="o">=</span><span class="mi">1000</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">cached_search</span><span class="p">(</span><span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">limit</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">20</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</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 (d:Document)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE text_search(d.content, $query)
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN d.doc_id, d.title, text_score(d) AS score
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY score DESC
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT $limit
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"query"</span><span class="p">:</span> <span class="n">query</span><span class="p">,</span> <span class="s2">"limit"</span><span class="p">:</span> <span class="n">limit</span><span class="p">})</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">result</span>
</span></span></code></pre></div>
<h3 id="evaluation-and-tuning" class="position-relative d-flex align-items-center group">
<span>Evaluation and 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="evaluation-and-tuning"
aria-haspopup="dialog"
aria-label="Share link: Evaluation and 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>
</h3>
<h4 id="precisionrecall-analysis" class="position-relative d-flex align-items-center group">
<span>Precision/Recall Analysis</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="precisionrecall-analysis"
aria-haspopup="dialog"
aria-label="Share link: Precision/Recall Analysis">
<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">Compute</span><span class="w"> </span><span class="py">precision</span><span class="nd">@k</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">recall</span><span class="nd">@k</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="err">'</span><span class="py">doc1</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">doc2</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">doc3</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">doc4</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">doc5</span><span class="err">'</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relevant_docs</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">text_search</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">,</span><span class="w"> </span><span class="nv">$query</span><span class="p">)</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="py">d</span><span class="p">,</span><span class="w"> </span><span class="py">text_score</span><span class="p">(</span><span class="py">d</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">score</span><span class="p">,</span><span class="w"> </span><span class="py">relevant_docs</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">score</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">10</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="py">COLLECT</span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">doc_id</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">retrieved_docs</span><span class="p">,</span><span class="w"> </span><span class="py">relevant_docs</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="py">SIZE</span><span class="p">([</span><span class="py">id</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">retrieved_docs</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">relevant_docs</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">hits</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">(</span><span class="py">retrieved_docs</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">k</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">(</span><span class="py">relevant_docs</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total_relevant</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">hits</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="py">k</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">precision_at_10</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">hits</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="py">total_relevant</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">recall_at_10</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">2</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="p">(</span><span class="py">precision_at_10</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">recall_at_10</span><span class="p">)</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="p">(</span><span class="py">precision_at_10</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">recall_at_10</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">f1_score</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="parameter-tuning-1" class="position-relative d-flex align-items-center group">
<span>Parameter 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="parameter-tuning-1"
aria-haspopup="dialog"
aria-label="Share link: Parameter 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-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Grid</span><span class="w"> </span><span class="py">search</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">optimal</span><span class="w"> </span><span class="py">k1</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">b</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">0</span><span class="mf">.5</span><span class="p">,</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="p">,</span><span class="w"> </span><span class="py">1</span><span class="mf">.2</span><span class="p">,</span><span class="w"> </span><span class="py">1</span><span class="mf">.5</span><span class="p">,</span><span class="w"> </span><span class="py">2</span><span class="mf">.0</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">k1_values</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">[</span><span class="py">0</span><span class="mf">.0</span><span class="p">,</span><span class="w"> </span><span class="py">0</span><span class="mf">.25</span><span class="p">,</span><span class="w"> </span><span class="py">0</span><span class="mf">.5</span><span class="p">,</span><span class="w"> </span><span class="py">0</span><span class="mf">.75</span><span class="p">,</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">b_values</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UNWIND</span><span class="w"> </span><span class="py">k1_values</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">k1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UNWIND</span><span class="w"> </span><span class="py">b_values</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">b</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="py">CALL</span><span class="w"> </span><span class="p">{</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="py">k1</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><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">Recreate</span><span class="w"> </span><span class="py">index</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">DROP</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">EXISTS</span><span class="w"> </span><span class="py">test_index</span><span class="err">;</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">TEXT</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">test_index</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="p">:</span><span class="nc">Document</span><span class="p">)</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">d</span><span class="err">.</span><span class="py">content</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">OPTIONS</span><span class="w"> </span><span class="p">{</span><span class="py">k1</span><span class="p">:</span><span class="w"> </span><span class="nc">k1</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">:</span><span class="w"> </span><span class="nc">b</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">Run</span><span class="w"> </span><span class="py">evaluation</span><span class="w"> </span><span class="py">queries</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">CALL</span><span class="w"> </span><span class="py">evaluate_queries</span><span class="p">()</span><span class="w"> </span><span class="py">YIELD</span><span class="w"> </span><span class="py">avg_ndcg</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">k1</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">,</span><span class="w"> </span><span class="py">avg_ndcg</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">k1</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">,</span><span class="w"> </span><span class="py">avg_ndcg</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">avg_ndcg</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">1</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="further-reading-1" class="position-relative d-flex align-items-center group">
<span>Further Reading</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="further-reading-1"
aria-haspopup="dialog"
aria-label="Share link: Further Reading">
<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><strong>BM25 Algorithm</strong>: Theory, Variants (BM25+, BM25F), and Applications</li>
<li><strong>Text Analysis</strong>: Tokenization, Stemming, and Language Processing</li>
<li><strong>Query Expansion</strong>: Pseudo-Relevance Feedback and Synonym Handling</li>
<li><strong>Hybrid Search</strong>: Combining BM25 with Vector Search (HNSW)</li>
<li><strong>Index Optimization</strong>: Sharding, Compression, and Caching</li>
</ul>
<p>Browse tagged content for complete BM25 and full-text search documentation.</p>
Tag
1 article
Tag: BM25 Ranking Algorithm
Explore Geode documentation tagged with bm25. Learn about bm25 features, best practices, and implementation details.