This commit is contained in:
Dylan Couzon
2026-09-09 22:09:58 -04:00
parent 45ca828f2c
commit 55b6484c64
88 changed files with 616 additions and 1127 deletions
@@ -32,8 +32,6 @@ jobs:
curl -sf http://localhost:1314/ >/dev/null && break
sleep 1
done
- name: Learn Navigation Check
run: python3 automation/check-learn.py --public qdrant-landing/public
- name: Internal Links Check
id: lychee
uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2.9.0
+20
View File
@@ -284,6 +284,26 @@ hideInSidebar: true
If `true`, the page will not be shown in the sidebar. It can be used in regular documentation and section pages (_index.md).
### Learn
The Learn portal (`/learn/`) groups four resources: Guides, Tutorials & Examples, Courses, and Articles. The sidebar for `partition: learn` pages is built by `themes/qdrant-2024/layouts/partials/documentation/learn-menu.html` from the content below.
#### Guides
A guide section is a directory under `content/documentation/` whose `_index.md` sets `partition: learn` and `learning_kind: guides`. Its pages inherit both values through `cascade` or set them directly. The sidebar, the Guides tab, and the section landing page list the section's pages by `weight`.
Set `guide_series: true` on pages that form an ordered series. The section's `guide_series_title` names the series, and `weight` sets the order of the numbered cards and the previous/next links.
When a page moves into a guide section, add its former URL to `aliases`.
#### Tutorials & Examples
`data/examples.yaml` is the catalog behind `/learn/examples/`. Each entry names an existing tutorial page and adds a `goal`, a `stack`, and optional `keywords` and `resources` links. The card title and description come from the tutorial's front matter, so the catalog never copies page content. The build fails if an entry points to a missing page or to a resource URL the tutorial no longer links.
#### Articles
An article is listed under the category page in `content/articles/<category>/_index.md` that matches its `category`. To retire an article, set `draft: true` and add a `301` line to `static/_redirects`.
## Blog
To add a new blog post, run the following commands:
-140
View File
@@ -1,140 +0,0 @@
#!/usr/bin/env python3
"""Check a Hugo build of Learn: python3 automation/check-learn.py --public PATH."""
import argparse
import hashlib
from html.parser import HTMLParser
import json
from pathlib import Path
import re
from urllib.parse import urlsplit, unquote
class Page(HTMLParser):
def __init__(self, text):
super().__init__()
self.links, self.ids, self.guides = set(), set(), set()
self.examples, self.neighbors, self.redirect = 0, {}, None
self.feed(text)
def handle_starttag(self, tag, attrs):
attr = dict(attrs)
if attr.get('id'):
self.ids.add(attr['id'])
if 'data-example' in attr:
self.examples += 1
if tag == 'a' and attr.get('href'):
href = attr['href']
self.links.add(href)
if 'data-guide-link' in attr:
self.guides.add(urlsplit(href).path)
if attr.get('rel') in ('prev', 'next'):
self.neighbors[attr['rel']] = urlsplit(href).path
if tag == 'meta' and attr.get('http-equiv', '').lower() == 'refresh':
self.redirect = urlsplit(attr.get('content', '').split('url=', 1)[-1]).path
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--public', type=Path, required=True)
args = parser.parse_args()
root = Path(__file__).resolve().parents[1]
manifest = json.loads((root / 'contributing/guide-sources.json').read_text())
errors, cache = [], {}
def page(route):
route = urlsplit(route).path
if route not in cache:
path = args.public / route.strip('/') / 'index.html'
if not path.exists():
errors.append(f'Missing page: {route}')
cache[route] = Page(path.read_text() if path.exists() else '')
return cache[route]
# Compare preserved guide text with the original source hash, allowing routing and presentation changes.
for entry in manifest['guides']:
source = root / entry['guide']
body = source.read_text().split('---', 2)[2]
original_title = '# ' + entry['title']
# Source documentation already contains its H1; migrated articles receive one for the docs layout.
if entry['added_title']:
body = body.replace(original_title, '', 1)
body = re.sub(r'{{< /?read-more >}}', '', body)
for other in manifest['guides']:
old = '/' + other['source'].split('content/', 1)[1].removesuffix('.md') + '/'
body = body.replace(old, other['url'])
digest = hashlib.sha256(re.sub(r'\s+', ' ', body).strip().encode()).hexdigest()
if digest != entry['body_sha256']:
errors.append(f'Guide source text changed: {source}')
if (root / entry['source']).exists():
errors.append(f'Duplicate source: {entry["source"]}')
if page(entry['url']).redirect:
errors.append(f'Guide must render its content: {entry["url"]}')
if '/articles/' in entry['source']:
old = '/articles/' + Path(entry['source']).stem + '/'
if page(old).redirect != entry['url']:
errors.append(f'Article redirect missing: {old}')
routes = {entry['url'] for entry in manifest['guides']}
for section, count in [('search-quality', 2), ('search-tuning', 8), ('production-patterns', 3)]:
route = '/documentation/' + section + '/'
links = {urlsplit(link).path for link in page(route).links}
expected = {e['url'] for e in manifest['guides'] if Path(e['guide']).parent.name == section}
if len(expected) != count or not expected <= links or page(route).guides != routes:
errors.append(f'Guide category has incorrect membership: {section}')
for landing in ['/learn/', '/documentation/guides/']:
if route not in {urlsplit(link).path for link in page(landing).links}:
errors.append(f'{landing} omits {route}')
series = [e['url'] for e in manifest['guides'] if '/search-tuning/' in e['url']]
for index, route in enumerate(series):
expected = {}
if index:
expected['prev'] = series[index - 1]
if index + 1 < len(series):
expected['next'] = series[index + 1]
if page(route).neighbors != expected:
errors.append(f'Series order incorrect: {route}')
for link in page(route).links:
target = urlsplit(link)
if target.path in series and target.fragment and unquote(target.fragment) not in page(target.path).ids:
errors.append(f'Broken series anchor: {link}')
entries = re.findall(r'^- page: (\S+)', (root / 'qdrant-landing/data/examples.yaml').read_text(), re.M)
catalog = page('/learn/examples/')
if catalog.examples != len(entries) or len(set(entries)) != len(entries):
errors.append('Catalog must show each registered tutorial exactly once')
if not {'example-query', 'example-goal', 'example-stack'} <= catalog.ids:
errors.append('Catalog filters are missing')
for route in entries:
route = route.lower()
if page(route).redirect:
errors.append(f'Tutorial source was replaced: {route}')
if route not in {urlsplit(link).path for link in catalog.links}:
errors.append(f'Tutorial missing from catalog: {route}')
if (args.public / 'learn/examples/index.md').read_text().count('[Open Example]') != len(entries):
errors.append('Markdown catalog differs from HTML catalog')
# Cascade rules suppress archive bodies in HTML, Markdown, and discovery indexes.
index = (root / 'qdrant-landing/content/articles/_index.md').read_text()
retired = re.search(r'path: /articles/\{([^}]+)\}', index)[1].split(',')
discovery = '\n'.join((args.public / name).read_text() for name in ['sitemap.xml', 'llms.txt', 'articles/index.md'])
for slug in retired:
source = root / 'qdrant-landing/content/articles' / (slug + '.md')
if not source.exists():
source = root / 'qdrant-landing/content/articles' / slug / '_index.md'
fm = source.read_text().split('---', 2)[1]
explicit = re.search(r'^slug:\s*(\S+)', fm, re.M)
route = '/articles/' + re.sub(r'[^\w-]', '', explicit[1].strip('"\'').lower() if explicit else slug) + '/'
path = args.public / route.strip('/')
if re.search(r'^draft: true\s*$', fm, re.M):
if (path / 'index.html').exists():
errors.append(f'Archived draft published: {route}')
continue
if page(route).redirect != '/articles/' or not (path / 'index.md').exists() or (path / 'index.md').read_text().strip() != '# Articles\n\nBrowse current Qdrant articles in [Articles](/articles/index.md).':
errors.append(f'Archive body exposed: {route}')
if route in discovery:
errors.append(f'Archive listed in discovery: {route}')
for slug in ['search-quality', 'embedding-research', 'qdrant-internals', 'production-ops']:
category = page('/articles/' + slug + '/')
if category.redirect:
errors.append(f'Active article category redirected: {slug}')
if errors:
raise SystemExit('\n'.join(errors))
print(f'PASS: {len(routes)} preserved guides; {len(series)} ordered series parts; {len(entries)} original tutorials; archive bodies excluded.')
-31
View File
@@ -1,31 +0,0 @@
# Maintain Learn
Learn has four resources: Guides, Tutorials & Examples, Courses, and Articles. Keep each piece in one source file and use the collections to make it discoverable.
## Tutorials & Examples
`qdrant-landing/data/examples.yaml` is the catalog. Each entry identifies an existing tutorial page, its goal, and its stack. Optional keywords improve search. Selected notebook and repository links appear in `resources`.
Hugo reads each title and description from the source tutorial. The catalog links to that page; it does not move or copy the tutorial. Both the HTML and Markdown catalog use the same entries. The browser filters the rendered cards without a separate search service.
Adding a tutorial requires one catalog entry. Use existing goal and stack labels where they fit. The build fails if the source page is missing or a selected resource URL no longer appears in the source tutorial.
## Guides
The three guide sections use `learning_kind: guides` and `partition: learn`. Topic cards and sidebar entries derive from their contents. Public URLs can remain stable through `url`, while `aliases` preserve former article URLs after a move.
The tuning series uses `guide_series: true` on its six pages. Their weights determine the order, numbered cards, and previous/next links. Standalone design guides remain outside that sequence.
`contributing/guide-sources.json` records the existing source for each migrated guide. Its hashes protect the preserved source text while allowing the routing and presentation changes recorded there. Review technical revisions separately from navigation changes.
## Articles
An article's `category` remains its normal topic field. The Articles index contains the few compatibility mappings needed for the four public topics. Authors can use Search Quality, Embedding Research, Qdrant Internals, or Production Ops directly for new articles.
The index also contains the archive cascade. It makes the listed pages redirect, excludes them from discovery, and suppresses their bodies in HTML and Markdown. Their original source files remain untouched. Apply retirement rules there instead of editing each archived article.
## Verify Changes
Build Hugo, then run `python3 automation/check-learn.py --public qdrant-landing/public`. The check covers preserved guide text, category membership, series navigation, catalog links, redirects, and archive exclusions. The existing redirect audit remains part of CI.
Check search, filters, Clear Filters, and a narrow-screen layout in the preview before submitting navigation changes.
-109
View File
@@ -1,109 +0,0 @@
{
"baseline": "0490e1e38cde035eacece7ca185e5ff44bbca32e",
"guides": [
{
"source": "qdrant-landing/content/documentation/improve-search/retrieval-relevance.md",
"guide": "qdrant-landing/content/documentation/search-quality/retrieval-relevance.md",
"url": "/documentation/improve-search/retrieval-relevance/",
"title": "Measuring Retrieval Relevance",
"body_sha256": "4809cf786abb14b818800e002d2b505bb8ce80fad66df477f1ec513fd02b2926",
"added_title": false
},
{
"source": "qdrant-landing/content/documentation/improve-search/pipeline-output-quality.md",
"guide": "qdrant-landing/content/documentation/search-quality/pipeline-output-quality.md",
"url": "/documentation/improve-search/pipeline-output-quality/",
"title": "Evaluating Pipeline Output Quality",
"body_sha256": "2673b05d442d7adbf6ffc98c3cebd2658fd41a533b6776f98f74c7a0d399defa",
"added_title": false
},
{
"source": "qdrant-landing/content/documentation/improve-search/query-decomposition.md",
"guide": "qdrant-landing/content/documentation/search-tuning/query-decomposition.md",
"url": "/documentation/improve-search/query-decomposition/",
"title": "Query Decomposition for Multi-Hop Questions",
"body_sha256": "2d7a8721d8d796706d4d7c4eea9a582fa890dcf8c673ad3f757fd9126b859178",
"added_title": false
},
{
"source": "qdrant-landing/content/articles/how-to-choose-an-embedding-model.md",
"guide": "qdrant-landing/content/documentation/search-tuning/choose-embedding-model.md",
"url": "/documentation/search-quality/choose-embedding-model/",
"title": "How to Choose an Embedding Model: Evaluation & Tradeoffs",
"body_sha256": "45db72823411381133ce3f6ef2ec103c0d6068315a7c6de27baf2ce37488506d",
"added_title": true
},
{
"source": "qdrant-landing/content/articles/multitenancy.md",
"guide": "qdrant-landing/content/documentation/production-patterns/multitenant-search.md",
"url": "/documentation/production-patterns/multitenant-search/",
"title": "How to Implement Multitenancy and Custom Sharding in Qdrant",
"body_sha256": "47b7150fdb34474e743884ea4977a0bd1889dd1edf184e450056bf277b75e6df",
"added_title": false
},
{
"source": "qdrant-landing/content/articles/bulk-uploads-in-qdrant.md",
"guide": "qdrant-landing/content/documentation/production-patterns/bulk-data-import.md",
"url": "/documentation/production-patterns/bulk-data-import/",
"title": "Bulk Uploading Data to Qdrant",
"body_sha256": "11c1166ab98a23f5cac181e485bd55c5178ef7a1376e4cdee7333e4d1ba72de6",
"added_title": true
},
{
"source": "qdrant-landing/content/articles/memory-tiers-in-qdrant-what-to-use-and-when.md",
"guide": "qdrant-landing/content/documentation/production-patterns/memory-tiers.md",
"url": "/documentation/production-patterns/memory-tiers/",
"title": "Memory Tiers in Qdrant: What to Use and When",
"body_sha256": "e28a3be091a91e2675033086b05e03788bf944ea9894a8159c5bcadb9c9f52b5",
"added_title": true
},
{
"source": "qdrant-landing/content/articles/hybrid-search.md",
"guide": "qdrant-landing/content/documentation/search-tuning/hybrid-search.md",
"url": "/documentation/search-tuning/hybrid-search/",
"title": "Hybrid Search in Qdrant",
"body_sha256": "de19a6ef0520904a1e7b9b63f4ba663b82b110683730a1b015d72543da71cb3b",
"added_title": true
},
{
"source": "qdrant-landing/content/articles/before-tuning-a-qdrant-collection.md",
"guide": "qdrant-landing/content/documentation/search-tuning/before-tuning-a-qdrant-collection.md",
"url": "/documentation/search-tuning/before-tuning-a-qdrant-collection/",
"title": "What to Check Before Tuning a Qdrant Collection",
"body_sha256": "16b896e07cea553faced53467a2d1d1530a6b17ae716546a3b4db9f8121f0d82",
"added_title": false
},
{
"source": "qdrant-landing/content/articles/candidate-depth.md",
"guide": "qdrant-landing/content/documentation/search-tuning/candidate-depth.md",
"url": "/documentation/search-tuning/candidate-depth/",
"title": "Candidate Depth: How Much Retrieval Is Enough?",
"body_sha256": "4a62dc32ef582437e87cbb5ed4f6839d99173dada631a3aeca82515a8566a4e0",
"added_title": false
},
{
"source": "qdrant-landing/content/articles/how-to-tune-hybrid-search.md",
"guide": "qdrant-landing/content/documentation/search-tuning/how-to-tune-hybrid-search.md",
"url": "/documentation/search-tuning/how-to-tune-hybrid-search/",
"title": "How to Tune Hybrid Search in Qdrant",
"body_sha256": "ac5ff44ad1e7ec60ae96f27e9511e782eb461fb7ca532b1f01271b6200f434f3",
"added_title": true
},
{
"source": "qdrant-landing/content/articles/when-a-reranker-is-worth-it.md",
"guide": "qdrant-landing/content/documentation/search-tuning/when-a-reranker-is-worth-it.md",
"url": "/documentation/search-tuning/when-a-reranker-is-worth-it/",
"title": "When Is a Reranker Worth It?",
"body_sha256": "08b380373ea6efb9350a4ba49a59cf05d6f5a8c13e3d6bb4adc41a47eb7878c8",
"added_title": false
},
{
"source": "qdrant-landing/content/articles/when-your-collection-outgrows-ram.md",
"guide": "qdrant-landing/content/documentation/search-tuning/when-your-collection-outgrows-ram.md",
"url": "/documentation/search-tuning/when-your-collection-outgrows-ram/",
"title": "When Your Collection Outgrows RAM",
"body_sha256": "ebca984ca16a8a307e35af82318bf2eb0649cdb606bf96a104dd0bf6f83d8253",
"added_title": true
}
]
}
+3 -9
View File
@@ -136,14 +136,8 @@ disableKinds = ["taxonomy", "term"]
id = 'G-NZYW2651NE'
[server]
# Local previews must show the same navigation after content moves.
[[server.headers]]
[server.headers]
for = '/get_anonymous_id/**'
[server.headers.values]
Cache-Control = 'no-store'
[[server.headers.values]]
Content-Security-Policy = 'frame-ancestors https://localhost:3000'
X-Frame-Options = 'ALLOW-FROM https://localhost:3000'
[[server.headers]]
for = '/**'
[server.headers.values]
Cache-Control = 'no-store'
X-Frame-Options = 'ALLOW-FROM https://localhost:3000'
+1 -17
View File
@@ -1,7 +1,7 @@
---
title: Qdrant Articles
page_title: Articles about Vector Search
short_description: Long-form articles on vector search, RAG, quantization, hybrid retrieval, and Qdrant internals from the engineering team.
short_description: "Long-form articles on vector search, RAG, quantization, hybrid retrieval, and Qdrant internals from the engineering team."
description: Articles about vector search and similarity larning related topics. Latest updates on Qdrant vector search engine.
section_title: Check out our latest publications
subtitle: Check out our latest publications
@@ -10,20 +10,4 @@ partition: learn
learnButton: Learn More
isMainPage: true
toc_start_level: 2
cascade:
- _target:
path: /articles/{agentic-builders-guide,agentic-rag,batch-vector-search-with-qdrant,binary-quantization,binary-quantization-openai,cars-recognition,core-concepts,data-exploration,data-privacy,dataset-quality,dedicated-service,demos-and-tutorials,detecting-coffee-anomalies,discovery-search,distance-based-exploration,embedding-recycler,faq-question-answering,fastembed,food-discovery-demo,indexing-optimization,langchain-integration,mastering-search,memory-consumption,metric-learning-tips,modern-sparse-neural-retrieval,neural-search-tutorial,product-quantization,qa-with-cohere-and-qdrant,rag-and-agents,rag-is-dead,rapid-rag-optimization-with-qdrant-and-quotient,search-as-you-type,search-feedback-loop,semantic-cache-ai-data-retrieval,serverless,storing-multiple-vectors-per-object-in-qdrant,triplet-loss,vector-search-filtering,vector-search-production,vector-search-resource-optimization,vector-similarity-beyond-search,what-are-embeddings,what-is-a-vector-database,what-is-quantization,what-is-rag-in-ai}
layout: redirect
redirect_to: /articles/
hideFromList: true
sitemapExclude: true
build:
list: never
render: always
publishResources: false
category_aliases:
mastering-search: embedding-research
category_overrides:
/articles/dedicated-vector-search/: qdrant-internals
/articles/sparse-vectors/: embedding-research
---
@@ -15,6 +15,7 @@ tags:
- Information Retrieval
category: mastering-search
weight: 100
draft: true
---
# How to Optimize Vector Search Using Batch Search in Qdrant 0.10.0
@@ -12,7 +12,7 @@ keywords:
- system architecture
- vector search
- vector database
category: core-concepts
category: qdrant-internals
---
Any problem with even a bit of complexity requires a specialized solution. You can use a Swiss Army knife to open a bottle or poke a hole in a cardboard box, but you will need an axe to chop wood — the same goes for software.
@@ -5,5 +5,5 @@ description: Explore the research behind modern embeddings and neural retrieval.
category: embedding-research
url: /articles/embedding-research/
isCategoryPage: true
weight: 60
weight: 35
---
@@ -6,4 +6,5 @@ category: mastering-search
url: /articles/mastering-search/
isCategoryPage: true
weight: 20
draft: true
---
@@ -7,7 +7,7 @@ social_preview_image: /articles_data/muvera-embeddings/preview/social_preview.jp
author: Kacper Łukawski
author_link: https://kacperlukawski.com
date: 2025-09-05T00:00:00.000Z
category: mastering-search
category: embedding-research
weight: 60
---
@@ -12,6 +12,7 @@ author_link: https://blog.vasnetsov.com/
date: 2021-06-10T10:18:00.000Z
category: demos-and-tutorials
# aliases: [ /articles/neural-search-tutorial/ ]
draft: true
---
# Neural Search 101: A Comprehensive Guide and Step-by-Step Tutorial
@@ -21,7 +21,7 @@ category: search-quality
Most retrieval systems run one pipeline on every query, and it is the wrong default in both directions: a single pass under-serves the hard queries, while reranking or rewriting every query wastes compute on the easy ones. Worse, the single pass fails silently. When the relevant document never reaches the top, the system answers anyway from whatever it got, with no sign anything went wrong.
The expensive fixes are well understood, [cross-encoders](/documentation/fastembed/fastembed-rerankers/), [ColBERT late interaction](/articles/late-interaction-models/), query rewriting, and [decomposition](/documentation/improve-search/query-decomposition/), so the real question is when to spend them: ideally you catch a weak retrieval cheaply, before paying for any of them, and escalate only the queries that need it. But what tells you, cheaply, that a retrieval is weak? That depends on how your retrieval fails, and we measure it across three corpora.
The expensive fixes are well understood, [cross-encoders](/documentation/fastembed/fastembed-rerankers/), [ColBERT late interaction](/articles/late-interaction-models/), query rewriting, and [decomposition](/documentation/search-tuning/query-decomposition/), so the real question is when to spend them: ideally you catch a weak retrieval cheaply, before paying for any of them, and escalate only the queries that need it. But what tells you, cheaply, that a retrieval is weak? That depends on how your retrieval fails, and we measure it across three corpora.
## What "Weak Retrieval" Means
@@ -165,4 +165,4 @@ This sits alongside corrective and adaptive retrieval. The difference is where t
- [Adaptive-RAG](https://arxiv.org/abs/2403.14403) routes on query complexity *before* retrieving, the question-shape approach this article argues against: gate on the evidence you got back, not the shape of the question.
- [Sufficient-context work](https://arxiv.org/abs/2411.06037) asks the same "is this enough?" question with an LLM judge rather than a free signal.
*The full loop, corrective actions, and evaluation harness are in the [self-correcting retrieval loops workshop](https://github.com/qdrant-labs/self-correcting-loops-workshop). For the building blocks it escalates to, see [late interaction models](/articles/late-interaction-models/), [hybrid search](/articles/hybrid-search/), and [query decomposition](/documentation/improve-search/query-decomposition/).*
*The full loop, corrective actions, and evaluation harness are in the [self-correcting retrieval loops workshop](https://github.com/qdrant-labs/self-correcting-loops-workshop). For the building blocks it escalates to, see [late interaction models](/articles/late-interaction-models/), [hybrid search](/articles/hybrid-search/), and [query decomposition](/documentation/search-tuning/query-decomposition/).*
@@ -5,5 +5,5 @@ description: Operate Qdrant at scale. Learn how to optimize memory and resources
category: production-ops
url: /articles/production-ops/
isCategoryPage: true
weight: 40
weight: 55
---
@@ -8,7 +8,7 @@ weight: 10
author: Thierry Damiba
author_link: https://github.com/thierrydamiba
date: 2026-03-09T00:00:00.000Z
category: mastering-search
category: embedding-research
---
*This is Part 1 of a 5-part series on fine-tuning sparse embeddings for e-commerce search. We'll go from "why bother?" to a production system that beats BM25 by 28%.*
@@ -8,7 +8,7 @@ weight: 20
author: Thierry Damiba
author_link: https://github.com/thierrydamiba
date: 2026-03-09T00:00:00.000Z
category: mastering-search
category: embedding-research
---
*This is Part 2 of a 5-part series on fine-tuning sparse embeddings for e-commerce search. In [Part 1](/articles/sparse-embeddings-ecommerce-part-1/), we covered why sparse embeddings beat BM25 for e-commerce. Now we build the training pipeline.*
@@ -8,7 +8,7 @@ weight: 30
author: Thierry Damiba
author_link: https://github.com/thierrydamiba
date: 2026-03-09T00:00:00.000Z
category: mastering-search
category: embedding-research
---
*This is Part 3 of a 5-part series on fine-tuning sparse embeddings for e-commerce search. In [Part 2](/articles/sparse-embeddings-ecommerce-part-2/), we trained a SPLADE model on Modal. Now we evaluate it and push further with hard negative mining.*
@@ -8,7 +8,7 @@ weight: 40
author: Thierry Damiba
author_link: https://github.com/thierrydamiba
date: 2026-03-09T00:00:00.000Z
category: mastering-search
category: embedding-research
---
*This is Part 4 of a 5-part series on fine-tuning sparse embeddings for e-commerce search. In [Part 3](/articles/sparse-embeddings-ecommerce-part-3/), we evaluated our model and implemented hard negative mining. Now we test how well it generalizes.*
@@ -8,7 +8,7 @@ weight: 50
author: Thierry Damiba
author_link: https://github.com/thierrydamiba
date: 2026-03-09T00:00:00.000Z
category: mastering-search
category: embedding-research
---
*This is Part 5 of a series on fine-tuning sparse embeddings for e-commerce search. Parts [1](/articles/sparse-embeddings-ecommerce-part-1/)–[4](/articles/sparse-embeddings-ecommerce-part-4/) built the pipeline from scratch. This article packages it into a tool anyone can use.*
@@ -15,7 +15,7 @@ keywords:
- SPLADE
- hybrid search
- vector search
category: core-concepts
category: embedding-research
---
Think of a library with a vast index card system. Each index card only has a few keywords marked out (sparse vector) of a large possible set for each book (document). This is what sparse vectors enable for text.
@@ -16,6 +16,7 @@ tags:
- Similarity Search
category: mastering-search
weight: 90
draft: true
---
# How to Optimize Vector Storage by Storing Multiple Vectors Per Object
@@ -154,7 +154,7 @@ Both methods combine scores from multiple retrieval legs (for example, dense and
For custom fusion, use the [Formula Query](/documentation/search/search-relevance/#score-boosting). For example, you can use decay functions to normalize both scores to a 0-1 range and then fuse them. This approach requires you to determine the approximate score distribution for each corpus, since you can't set decay function parameters dynamically. The Formula Query doesn't support custom rank-based fusion because it doesn't have access to prefetch ranks; only to the raw scores.
To evaluate which works better for your use case, create a small golden query set and compare [retrieval quality metrics](/documentation/improve-search/retrieval-relevance/) (for example, NDCG@10) under each method.
To evaluate which works better for your use case, create a small golden query set and compare [retrieval quality metrics](/documentation/search-quality/retrieval-relevance/) (for example, NDCG@10) under each method.
See also: the [Choosing a Fusion Method](/documentation/search/hybrid-queries/#choosing-a-fusion-method) decision table in the Hybrid Queries reference, and the [Choosing a Fusion Method notebook](https://github.com/qdrant/examples/blob/master/fusion-methods/Choosing_a_Fusion_Method.ipynb) for a runnable RRF vs weighted RRF vs DBSF eval on BEIR/SciFact with a reusable weight-tuning helper.
@@ -6,50 +6,49 @@ partition: learn
learning_kind: guides
breadcrumb: false
hideTOC: true
expandSidebar: true
slug: guides
hideInSidebar: true
build:
render: always
content:
- partial: documentation/banners/banner-a
title: Build Better Search
description: Practical guidance for evaluating and tuning search, choosing models, and planning how your application grows.
linkDescription: Start with the guide that matches your next decision.
cloudButton:
text: Explore Search Evaluation
url: /documentation/search-quality/
localButton:
text: Explore Production & Performance
url: /documentation/production-patterns/
- partial: documentation/guides/topics
- partial: documentation/sections/cards-section
title: Start with a Practical Guide
description: Work through a decision you can apply to your own search system.
cardsPartial: documentation/cards/docs-cards
cards:
- title: 'How to Choose an Embedding Model: Evaluation & Tradeoffs'
description: Compare relevance, language support, and serving cost before you rebuild document vectors.
icon:
src: /icons/outline/vectors-blue.svg
alt: ''
link:
text: Compare Models
url: /documentation/search-quality/choose-embedding-model/
- title: How to Implement Multitenancy and Custom Sharding in Qdrant
description: Choose shared collections, tenant filters, and shard placement as customer workloads grow.
icon:
src: /icons/outline/cloud-cog-teal.svg
alt: ''
link:
text: Plan Tenant Growth
url: /documentation/production-patterns/multitenant-search/
- title: Bulk Uploading Data to Qdrant
description: Plan batching, parallel uploads, sharding, and indexing for large datasets.
icon:
src: /icons/outline/refresh-cw-purple.svg
alt: ''
link:
text: Plan Your Import
url: /documentation/production-patterns/bulk-data-import/
- partial: documentation/banners/banner-a
title: Build Better Search
description: Practical guidance for evaluating and tuning search, choosing models, and planning how your application grows.
linkDescription: Start with the guide that matches your next decision.
cloudButton:
text: Explore Search Evaluation
url: /documentation/search-quality/
localButton:
text: Explore Production & Performance
url: /documentation/production-patterns/
- partial: documentation/guides/topics
- partial: documentation/sections/cards-section
title: Start with a Practical Guide
description: Work through a decision you can apply to your own search system.
cardsPartial: documentation/cards/docs-cards
cards:
- title: "How to Choose an Embedding Model: Evaluation & Tradeoffs"
description: Compare relevance, language support, and serving cost before you rebuild document vectors.
icon:
src: /icons/outline/vectors-blue.svg
alt: ""
link:
text: Compare Models
url: /documentation/search-tuning/choose-embedding-model/
- title: How to Implement Multitenancy and Custom Sharding in Qdrant
description: Choose shared collections, tenant filters, and shard placement as customer workloads grow.
icon:
src: /icons/outline/cloud-cog-teal.svg
alt: ""
link:
text: Plan Tenant Growth
url: /documentation/production-patterns/multitenant-search/
- title: Bulk Uploading Data to Qdrant
description: Plan batching, parallel uploads, sharding, and indexing for large datasets.
icon:
src: /icons/outline/refresh-cw-purple.svg
alt: ""
link:
text: Plan Your Import
url: /documentation/production-patterns/bulk-data-import/
---
@@ -5,6 +5,8 @@ description: "Define dense, sparse, and multivector configurations in Qdrant col
weight: 10
cta: "Try dense and sparse vectors with your own data in Cloud."
aliases:
- /articles/storing-multiple-vectors-per-object-in-qdrant/
- /blog/storing-multiple-vectors-per-object-in-qdrant/
- /vectors
---
@@ -9,26 +9,26 @@ hideTOC: true
breadcrumb: false
guide_icon: /icons/outline/cloud-cog-teal.svg
related:
- /documentation/manage-data/multitenancy/
- /documentation/manage-data/bulk-upload/
- /documentation/ops-optimization/read-write-contention/
- /documentation/capacity-planning/
- /documentation/manage-data/multitenancy/
- /documentation/manage-data/bulk-upload/
- /documentation/ops-optimization/read-write-contention/
- /documentation/capacity-planning/
content:
- partial: documentation/banners/banner-a
title: Production & Performance
description: Plan multitenancy, bulk uploads, and memory placement as your Qdrant application and vector collection grow.
linkDescription: Choose the pattern that matches your workload and its constraints.
cloudButton:
text: Serve Many Tenants
url: /documentation/production-patterns/multitenant-search/
localButton:
text: Plan a Data Import
url: /documentation/production-patterns/bulk-data-import/
- partial: documentation/guides/guide-cards
section: /documentation/production-patterns/
- partial: documentation/banners/banner-a
title: Production & Performance
description: Plan multitenancy, bulk uploads, and memory placement as your Qdrant application and vector collection grow.
linkDescription: Choose the pattern that matches your workload and its constraints.
cloudButton:
text: Serve Many Tenants
url: /documentation/production-patterns/multitenant-search/
localButton:
text: Plan a Data Import
url: /documentation/production-patterns/bulk-data-import/
- partial: documentation/guides/guide-cards
section: /documentation/production-patterns/
worked_examples:
- /documentation/tutorials-search-engineering/index-dynamic-payloads/
- /documentation/tutorials-search-engineering/branch-aware-search/
- /documentation/tutorials-operations/embedding-model-migration/
- /documentation/tutorials-search-engineering/index-dynamic-payloads/
- /documentation/tutorials-search-engineering/branch-aware-search/
- /documentation/tutorials-operations/embedding-model-migration/
---
@@ -1,25 +1,24 @@
---
title: Bulk Uploading Data to Qdrant
short_description: 'Plan bulk uploads in Qdrant at scale: batching, parallelization, sharding, payload indexes, quantization, and on-disk storage.'
description: 'Plan bulk uploads in Qdrant: batching, parallelization, sharding, payload indexes, quantization, and on-disk storage.'
title: "Bulk Uploading Data to Qdrant"
short_description: "Plan bulk uploads in Qdrant at scale: batching, parallelization, sharding, payload indexes, quantization, and on-disk storage."
description: "Plan bulk uploads in Qdrant: batching, parallelization, sharding, payload indexes, quantization, and on-disk storage."
preview_dir: /articles_data/bulk-uploads-in-qdrant/preview
social_preview_image: /articles_data/bulk-uploads-in-qdrant/preview/social_preview.jpg
weight: 35
author: John Kupchanko
author_link: https://github.com/jkupchanko
keywords:
- bulk upload
- vector database
- batching
- quantization
- sharding
date: 2026-07-14 00:00:00+00:00
- bulk upload
- vector database
- batching
- quantization
- sharding
date: 2026-07-14T00:00:00.000Z
draft: false
partition: learn
learning_kind: guides
url: /documentation/production-patterns/bulk-data-import/
aliases:
- /articles/bulk-uploads-in-qdrant/
- /articles/bulk-uploads-in-qdrant/
---
# Bulk Uploading Data to Qdrant
@@ -1,25 +1,24 @@
---
title: 'Memory Tiers in Qdrant: What to Use and When'
short_description: A guide to choosing a Qdrant memory tier layout as your collection grows.
description: Which Qdrant memory tier layout to use and when, and why, backed by benchmarks.
title: "Memory Tiers in Qdrant: What to Use and When"
short_description: "A guide to choosing a Qdrant memory tier layout as your collection grows."
description: "Which Qdrant memory tier layout to use and when, and why, backed by benchmarks."
social_preview_image: /articles_data/memory-tiers-in-qdrant-what-to-use-and-when/preview/social_preview.jpg
preview_dir: /articles_data/memory-tiers-in-qdrant-what-to-use-and-when/preview
author: Clelia Bertelli
author_link: https://qdrant.tech
date: 2026-08-28 10:00:00+02:00
date: 2026-08-28T10:00:00+02:00
draft: false
keywords:
- memory tiers
- caching
- disk
- scaling
- benchmark
- memory tiers
- caching
- disk
- scaling
- benchmark
weight: 8
partition: learn
learning_kind: guides
url: /documentation/production-patterns/memory-tiers/
aliases:
- /articles/memory-tiers-in-qdrant-what-to-use-and-when/
- /articles/memory-tiers-in-qdrant-what-to-use-and-when/
---
# Memory Tiers in Qdrant: What to Use and When
@@ -128,10 +127,6 @@ A story built only on point count, where more data always means a worse tail, do
## Adjacent Work
{{< read-more >}}
- [Memory tiers documentation](/documentation/ops-configuration/memory-tiers/): the full set of tier and quantization options per structure.
- [Storage documentation](/documentation/manage-data/storage/): how collections, segments, and storage structures fit together on disk.
- [qdrant-labs/memory-tiers-explained](https://github.com/qdrant-labs/memory-tiers-explained): the benchmark code and raw results behind the guidance in this piece.
{{< /read-more >}}
@@ -1,24 +1,23 @@
---
title: How to Implement Multitenancy and Custom Sharding in Qdrant
short_description: Explore how Qdrant's multitenancy and custom sharding streamline machine-learning operations, enhancing scalability and data security.
description: Discover how multitenancy and custom sharding in Qdrant can streamline your machine-learning operations. Learn how to scale efficiently and manage data securely.
title: "How to Implement Multitenancy and Custom Sharding in Qdrant"
short_description: "Explore how Qdrant's multitenancy and custom sharding streamline machine-learning operations, enhancing scalability and data security."
description: "Discover how multitenancy and custom sharding in Qdrant can streamline your machine-learning operations. Learn how to scale efficiently and manage data securely."
social_preview_image: /articles_data/multitenancy/preview/social_preview.jpg
preview_dir: /articles_data/multitenancy/preview
small_preview_image: /articles_data/multitenancy/icon.svg
weight: 60
author: David Myriel
date: 2024-02-06 13:21:00+00:00
date: 2024-02-06T13:21:00.000Z
draft: false
keywords:
- multitenancy
- custom sharding
- multiple partitions
- vector database
- multitenancy
- custom sharding
- multiple partitions
- vector database
partition: learn
learning_kind: guides
url: /documentation/production-patterns/multitenant-search/
aliases:
- /articles/multitenancy/
- /articles/multitenancy/
---
# Scaling Your Machine Learning Setup: The Power of Multitenancy and Custom Sharding in Qdrant
@@ -9,24 +9,24 @@ hideTOC: true
breadcrumb: false
guide_icon: /icons/outline/search-blue.svg
related:
- /documentation/search/
- /articles/search-quality/
- /documentation/search/
- /articles/search-quality/
content:
- partial: documentation/banners/banner-a
title: Search Evaluation
description: Build an evaluation baseline and measure whether your search system produces useful results.
linkDescription: Choose the evaluation method that matches the result you need to judge.
cloudButton:
text: Measure Retrieval Relevance
url: /documentation/improve-search/retrieval-relevance/
localButton:
text: Evaluate Pipeline Output
url: /documentation/improve-search/pipeline-output-quality/
- partial: documentation/guides/guide-cards
section: /documentation/search-quality/
- partial: documentation/banners/banner-a
title: Search Evaluation
description: Build an evaluation baseline and measure whether your search system produces useful results.
linkDescription: Choose the evaluation method that matches the result you need to judge.
cloudButton:
text: Measure Retrieval Relevance
url: /documentation/search-quality/retrieval-relevance/
localButton:
text: Evaluate Pipeline Output
url: /documentation/search-quality/pipeline-output-quality/
- partial: documentation/guides/guide-cards
section: /documentation/search-quality/
aliases:
- /documentation/improve-search/
- /documentation/improve-search/
worked_examples:
- /documentation/tutorials-search-engineering/ann-recall/
- /documentation/tutorials-search-engineering/ann-recall/
---
@@ -1,13 +1,13 @@
---
title: Evaluating Pipeline Output Quality
short_description: "Separate retrieval failures from generation failures and evaluate whether your full pipeline produces supported, useful answers."
description: "Evaluate retrieval and generation separately to identify why a Qdrant search pipeline returns an unsupported answer or misses the information users need."
weight: 7
aliases:
- /documentation/tutorials/retrieval-quality-pipeline-output/
- /documentation/improve-search/pipeline-output-quality/
- /documentation/tutorials/retrieval-quality-pipeline-output/
partition: learn
learning_kind: guides
url: /documentation/improve-search/pipeline-output-quality/
short_description: Separate retrieval failures from generation failures and evaluate whether your full pipeline produces supported, useful answers.
description: Evaluate retrieval and generation separately to identify why a Qdrant search pipeline returns an unsupported answer or misses the information users need.
---
# Evaluating Pipeline Output Quality
@@ -18,9 +18,9 @@ description: Evaluate retrieval and generation separately to identify why a Qdra
This tutorial focuses on **pipeline output quality**: whether the full retrieval pipeline produces the right output once retrieved results reach a consumer, most often an LLM generator in a RAG system.
To measure pipeline output quality, you run your golden set through the full pipeline, capture each `(question, retrieved_context, answer)` triple, and score the triples against judgment metrics like faithfulness, answer relevancy, and context precision.
Two related tutorials cover the other retrieval-evaluation concerns: [Measuring ANN Recall](/documentation/tutorials-search-engineering/ann-recall/) (does the approximate index match exact kNN?) and [Measuring Retrieval Relevance](/documentation/improve-search/retrieval-relevance/) (do the top-k results match query intent?).
Two related tutorials cover the other retrieval-evaluation concerns: [Measuring ANN Recall](/documentation/tutorials-search-engineering/ann-recall/) (does the approximate index match exact kNN?) and [Measuring Retrieval Relevance](/documentation/search-quality/retrieval-relevance/) (do the top-k results match query intent?).
**Prerequisites.** A Qdrant collection populated with your documents as points (vectors + a `text` payload field for the chunk content), a labeled golden set (see [Measuring Retrieval Relevance](/documentation/improve-search/retrieval-relevance/)), LLM access for generation and judging, and Python with `ragas` installed.
**Prerequisites.** A Qdrant collection populated with your documents as points (vectors + a `text` payload field for the chunk content), a labeled golden set (see [Measuring Retrieval Relevance](/documentation/search-quality/retrieval-relevance/)), LLM access for generation and judging, and Python with `ragas` installed.
## Wiring the RAG Pipeline
@@ -180,7 +180,7 @@ If you ship retrieval changes regularly, this evaluation earns its place in CI.
## Isolating Retrieval vs Generation
If you're also running [retrieval evaluation](/documentation/improve-search/retrieval-relevance/) against the same golden set, pairing the two scores on every run gives a diagnostic 2x2 for attributing score changes. When a metric drops after a change (new embedding model, new prompt, or new chunking strategy), the pair tells you which half of the pipeline to investigate.
If you're also running [retrieval evaluation](/documentation/search-quality/retrieval-relevance/) against the same golden set, pairing the two scores on every run gives a diagnostic 2x2 for attributing score changes. When a metric drops after a change (new embedding model, new prompt, or new chunking strategy), the pair tells you which half of the pipeline to investigate.
Pair `recall@10` from the retrieval evaluation with `faithfulness` from the pipeline-output evaluation. In the table, High and Low are relative to the target thresholds you set per metric.
@@ -1,13 +1,13 @@
---
title: Measuring Retrieval Relevance
short_description: "Build a labeled query set and measure whether retrieved documents answer users' questions, with query-level relevance metrics."
description: "Measure Qdrant retrieval relevance with labeled queries, document IDs, and ranking metrics to compare search configurations on your own data."
weight: 6
aliases:
- /documentation/tutorials/retrieval-quality-golden-set/
- /documentation/improve-search/retrieval-relevance/
- /documentation/tutorials/retrieval-quality-golden-set/
partition: learn
learning_kind: guides
url: /documentation/improve-search/retrieval-relevance/
short_description: Build a labeled query set and measure whether retrieved documents answer users' questions, with query-level relevance metrics.
description: Measure Qdrant retrieval relevance with labeled queries, document IDs, and ranking metrics to compare search configurations on your own data.
---
# Measuring Retrieval Relevance
@@ -18,7 +18,7 @@ description: Measure Qdrant retrieval relevance with labeled queries, document I
This tutorial focuses on **retrieval relevance**: how well retrieved results match real user intent.
To measure retrieval relevance, you need a labeled dataset of queries paired with their expected relevant documents (commonly called a *golden query set* or *ground truth*). This tutorial covers both building that dataset and running it through Qdrant to compute relevance metrics.
Two related tutorials cover the other retrieval-evaluation concerns: [Measuring ANN Recall](/documentation/tutorials-search-engineering/ann-recall/) (does the approximate index match exact kNN?) and [Evaluating Pipeline Output Quality](/documentation/improve-search/pipeline-output-quality/) (does the end-to-end pipeline produce the right output?).
Two related tutorials cover the other retrieval-evaluation concerns: [Measuring ANN Recall](/documentation/tutorials-search-engineering/ann-recall/) (does the approximate index match exact kNN?) and [Evaluating Pipeline Output Quality](/documentation/search-quality/pipeline-output-quality/) (does the end-to-end pipeline produce the right output?).
**Prerequisites.** A Qdrant collection populated with your documents as points (vectors + optional payload), an embedding model available to encode queries at evaluation time, and Python with `ranx` installed.
@@ -180,4 +180,4 @@ In golden sets, **data leakage** means any setup that makes offline metrics look
## Next Steps
Once retrieval relevance is on target, the next layer is pipeline output quality: whether the full pipeline produces the right output when retrieval feeds into a consumer (LLM generator, ranker, or UI). See [Evaluating Pipeline Output Quality](/documentation/improve-search/pipeline-output-quality/).
Once retrieval relevance is on target, the next layer is pipeline output quality: whether the full pipeline produces the right output when retrieval feeds into a consumer (LLM generator, ranker, or UI). See [Evaluating Pipeline Output Quality](/documentation/search-quality/pipeline-output-quality/).
@@ -1,25 +1,27 @@
---
title: Search Design & Tuning
short_description: Choose embedding models and retrieval strategies, then tune candidate depth, fusion, reranking, and memory against your search goals.
description: 'Design and tune Qdrant search: choose embeddings and retrieval strategies, then evaluate changes to candidate depth, fusion, reranking, and memory.'
short_description: Choose embedding models, filters, and retrieval strategies, then tune candidate depth, fusion, reranking, and memory against your search goals.
description: "Design and tune Qdrant search: choose embeddings and retrieval strategies, then evaluate changes to candidate depth, fusion, reranking, and memory."
partition: learn
learning_kind: guides
weight: 125
hideTOC: true
breadcrumb: false
aliases:
- /articles/mastering-search/
guide_icon: /icons/outline/speedometer-blue.svg
content:
- partial: documentation/banners/banner-a
title: Search Design & Tuning
description: Choose a search approach, then use evaluation results to decide what to change.
linkDescription: Start with a design decision or follow the complete retrieval tuning series.
cloudButton:
text: Choose an Embedding Model
url: /documentation/search-quality/choose-embedding-model/
localButton:
text: Start the Tuning Series
url: /documentation/search-tuning/hybrid-search/
- partial: documentation/guides/guide-cards
section: /documentation/search-tuning/
- partial: documentation/banners/banner-a
title: Search Design & Tuning
description: Choose a search approach, then use evaluation results to decide what to change.
linkDescription: Start with a design decision or follow the complete retrieval tuning series.
cloudButton:
text: Choose an Embedding Model
url: /documentation/search-tuning/choose-embedding-model/
localButton:
text: Start the Tuning Series
url: /documentation/search-tuning/hybrid-search/
- partial: documentation/guides/guide-cards
section: /documentation/search-tuning/
guide_series_title: Tune Your Retrieval Pipeline
---
@@ -1,24 +1,24 @@
---
title: What to Check Before Tuning a Qdrant Collection
short_description: Seven collection settings that degrade retrieval without an error, the order to try changes in, and how many labeled queries a gain needs.
description: 'Audit a Qdrant collection: find the settings that degrade retrieval silently, choose the cheapest next change, and size a labeled query set.'
title: "What to Check Before Tuning a Qdrant Collection"
short_description: "Seven collection settings that degrade retrieval without an error, the order to try changes in, and how many labeled queries a gain needs."
description: "Audit a Qdrant collection: find the settings that degrade retrieval silently, choose the cheapest next change, and size a labeled query set."
preview_dir: /articles_data/before-tuning-a-qdrant-collection/preview
social_preview_image: /articles_data/before-tuning-a-qdrant-collection/preview/social_preview.jpg
weight: 120
author: Dylan Couzon
author_link: https://www.linkedin.com/in/dcouzon/
date: 2026-08-20 00:00:00+03:00
date: 2026-08-20T00:00:00+03:00
draft: false
keywords:
- retrieval tuning
- search relevance
- nDCG
- labeled query set
- Qdrant collection audit
- retrieval tuning
- search relevance
- nDCG
- labeled query set
- Qdrant collection audit
partition: learn
learning_kind: guides
aliases:
- /articles/before-tuning-a-qdrant-collection/
- /articles/before-tuning-a-qdrant-collection/
guide_series: true
---
@@ -39,7 +39,7 @@ If you run dense-only search and exact keywords are missing from results, hybrid
Before you tune:
1. Check that vectors are indexed and that every field used in a filter has a payload index. [Collection details](/documentation/manage-data/collections/#collection-info) and [payload indexing](/documentation/manage-data/indexing/#payload-index) show what to inspect.
2. Build a labeled query set and choose a metric that matches the product experience. A labeled query pairs a real user query with the documents that should be returned. [Measuring retrieval relevance](/documentation/improve-search/retrieval-relevance/) walks through the setup.
2. Build a labeled query set and choose a metric that matches the product experience. A labeled query pairs a real user query with the documents that should be returned. [Measuring retrieval relevance](/documentation/search-quality/retrieval-relevance/) walks through the setup.
## The Symptom Tells You Where to Start
@@ -130,7 +130,7 @@ Choose the metric before you compare settings, because the metric decides the wi
## Make Sure Your Labels Can Detect a Gain
[Retrieval relevance](/documentation/improve-search/retrieval-relevance/) covers building a labeled set. Its size decides whether any retrieval tuning is visible to you at all.
[Retrieval relevance](/documentation/search-quality/retrieval-relevance/) covers building a labeled set. Its size decides whether any retrieval tuning is visible to you at all.
A labeled set is large enough when it can distinguish the improvement you care about from normal query-to-query variation. Size alone will not save an unrepresentative set. Pull queries across the mix your product sees, including its important query types and filters, and spot-check a sample of the labels yourself.
@@ -1,24 +1,24 @@
---
title: 'Candidate Depth: How Much Retrieval Is Enough?'
short_description: Raising candidate depth raises the best score a later ranking stage could reach, but default fusion barely used that extra room.
description: Set candidate depth and hnsw_ef in Qdrant, measure the gap between your ranking and a perfect one, and balance the trade-offs.
title: "Candidate Depth: How Much Retrieval Is Enough?"
short_description: "Raising candidate depth raises the best score a later ranking stage could reach, but default fusion barely used that extra room."
description: "Set candidate depth and hnsw_ef in Qdrant, measure the gap between your ranking and a perfect one, and balance the trade-offs."
preview_dir: /articles_data/candidate-depth/preview
social_preview_image: /articles_data/candidate-depth/preview/social_preview.jpg
weight: 130
author: Dylan Couzon
author_link: https://www.linkedin.com/in/dcouzon/
date: 2026-08-21 00:00:00+03:00
date: 2026-08-21T00:00:00+03:00
draft: false
keywords:
- candidate depth
- hnsw_ef
- scalar quantization
- memory tiers
- HNSW tuning
- candidate depth
- hnsw_ef
- scalar quantization
- memory tiers
- HNSW tuning
partition: learn
learning_kind: guides
aliases:
- /articles/candidate-depth/
- /articles/candidate-depth/
guide_series: true
---
@@ -1,19 +1,18 @@
---
title: 'How to Choose an Embedding Model: Evaluation & Tradeoffs'
short_description: There is no one-size-fits-all solution when it comes to embedding models. Learn how to choose the right one for your use case.
description: Building proper search requires selecting the right embedding model for your specific use case. This guide helps you navigate the selection process based on performance, cost, and other practical considerations.
title: "How to Choose an Embedding Model: Evaluation & Tradeoffs"
short_description: "There is no one-size-fits-all solution when it comes to embedding models. Learn how to choose the right one for your use case."
description: "Building proper search requires selecting the right embedding model for your specific use case. This guide helps you navigate the selection process based on performance, cost, and other practical considerations."
preview_dir: /articles_data/how-to-choose-an-embedding-model/preview
social_preview_image: /articles_data/how-to-choose-an-embedding-model/preview/social_preview.jpg
author: Kacper Łukawski
author_link: https://www.kacperlukawski.com
date: 2025-07-15 00:00:00+00:00
date: 2025-07-15T00:00:00.000Z
draft: false
weight: 10
partition: learn
learning_kind: guides
url: /documentation/search-quality/choose-embedding-model/
aliases:
- /articles/how-to-choose-an-embedding-model/
- /articles/how-to-choose-an-embedding-model/
---
# How to Choose an Embedding Model: Evaluation & Tradeoffs
@@ -1,24 +1,24 @@
---
title: How to Tune Hybrid Search in Qdrant
short_description: Tune hybrid search with RRF or DBSF, choose k from relevance labels, and learn why weights are pairs instead of ratios.
description: 'Tune hybrid search fusion in Qdrant: choose between RRF and DBSF, set the constant k from your relevance labels, and get weights right.'
title: "How to Tune Hybrid Search in Qdrant"
short_description: "Tune hybrid search with RRF or DBSF, choose k from relevance labels, and learn why weights are pairs instead of ratios."
description: "Tune hybrid search fusion in Qdrant: choose between RRF and DBSF, set the constant k from your relevance labels, and get weights right."
preview_dir: /articles_data/how-to-tune-hybrid-search/preview
social_preview_image: /articles_data/how-to-tune-hybrid-search/preview/social_preview.jpg
weight: 140
author: Dylan Couzon
author_link: https://www.linkedin.com/in/dcouzon/
date: 2026-08-22 00:00:00+03:00
date: 2026-08-22T00:00:00+03:00
draft: false
keywords:
- hybrid search tuning
- reciprocal rank fusion
- RRF k parameter
- fusion weights
- DBSF
- hybrid search tuning
- reciprocal rank fusion
- RRF k parameter
- fusion weights
- DBSF
partition: learn
learning_kind: guides
aliases:
- /articles/how-to-tune-hybrid-search/
- /articles/how-to-tune-hybrid-search/
guide_series: true
---
@@ -1,24 +1,24 @@
---
title: Hybrid Search in Qdrant
short_description: 'Run dense and sparse retrieval together: the queries each one gets wrong, what the second index costs, and how to tell if it helped.'
description: 'Decide whether to add hybrid search in Qdrant: the queries dense and sparse retrieval each get wrong, and how to measure the gain.'
title: "Hybrid Search in Qdrant"
short_description: "Run dense and sparse retrieval together: the queries each one gets wrong, what the second index costs, and how to tell if it helped."
description: "Decide whether to add hybrid search in Qdrant: the queries dense and sparse retrieval each get wrong, and how to measure the gain."
preview_dir: /articles_data/hybrid-search/preview
social_preview_image: /articles_data/hybrid-search/preview/social_preview.jpg
weight: 110
author: Dylan Couzon
author_link: https://www.linkedin.com/in/dcouzon/
date: 2026-08-24 09:00:00+03:00
date: 2026-08-24T09:00:00+03:00
draft: false
keywords:
- hybrid search
- sparse vectors
- BM25
- reciprocal rank fusion
- search relevance
- hybrid search
- sparse vectors
- BM25
- reciprocal rank fusion
- search relevance
partition: learn
learning_kind: guides
aliases:
- /articles/hybrid-search/
- /articles/hybrid-search/
guide_series: true
---
@@ -1,11 +1,12 @@
---
title: Query Decomposition for Multi-Hop Questions
short_description: 'Answer multi-hop questions by retrieving in steps: an LLM asks each follow-up sub-question, then fuse the per-hop results with RRF.'
description: 'Answer multi-hop questions in Qdrant: decompose the query into retrieval steps, let an LLM ask each follow-up, and fuse results with RRF.'
short_description: "Answer multi-hop questions by retrieving in steps: an LLM asks each follow-up sub-question, then fuse the per-hop results with RRF."
description: "Answer multi-hop questions in Qdrant: decompose the query into retrieval steps, let an LLM ask each follow-up, and fuse results with RRF."
weight: 20
aliases:
- /documentation/improve-search/query-decomposition/
partition: learn
learning_kind: guides
url: /documentation/improve-search/query-decomposition/
---
# Query Decomposition for Multi-Hop Questions
@@ -122,4 +123,4 @@ The birthplace chunk never mentions Inception, so the original question won't su
## When to Use It
Decomposition adds an LLM call and a query per hop, so reach for it only when a question spans multiple facts. For single-fact questions, one query is faster and just as accurate. To confirm it helps on your data, compare `recall@k` for single-pass against decomposition on a small set of multi-hop questions; the [Measuring Retrieval Relevance](/documentation/improve-search/retrieval-relevance/) tutorial covers the setup.
Decomposition adds an LLM call and a query per hop, so reach for it only when a question spans multiple facts. For single-fact questions, one query is faster and just as accurate. To confirm it helps on your data, compare `recall@k` for single-pass against decomposition on a small set of multi-hop questions; the [Measuring Retrieval Relevance](/documentation/search-quality/retrieval-relevance/) tutorial covers the setup.
@@ -1,15 +1,21 @@
---
title: "A Complete Guide to Filtering in Vector Search"
short_description: "Merging different search methods to improve the search quality was never easier"
short_description: "Apply payload filters, build payload indexes, and combine conditions to narrow Qdrant search results to the right data."
description: "Learn everything about filtering in Qdrant. Discover key tricks and best practices to boost semantic search performance and reduce Qdrant's resource usage."
preview_dir: /articles_data/vector-search-filtering/preview
social_preview_image: /articles_data/vector-search-filtering/preview/social_preview.jpg
weight: 70
weight: 30
author: Sabrina Aquino, David Myriel
author_link:
date: 2024-09-10T00:00:00.000Z
category: mastering-search
partition: learn
learning_kind: guides
aliases:
- /articles/vector-search-filtering/
---
# A Complete Guide to Filtering in Vector Search
Imagine you sell computer hardware. To help shoppers easily find products on your website, you need to have a **user-friendly [search engine](https://qdrant.tech)**.
![vector-search-ecommerce](/articles_data/vector-search-filtering/vector-search-ecommerce.png)
@@ -1,24 +1,24 @@
---
title: When Is a Reranker Worth It?
short_description: Rerank 10 candidates, compare with your tuned first stage on held-out queries, and raise the count only after the win holds.
description: Test whether a cross-encoder reranker beats your tuned first stage in Qdrant, then choose the model and candidate count from measured results.
title: "When Is a Reranker Worth It?"
short_description: "Rerank 10 candidates, compare with your tuned first stage on held-out queries, and raise the count only after the win holds."
description: "Test whether a cross-encoder reranker beats your tuned first stage in Qdrant, then choose the model and candidate count from measured results."
preview_dir: /articles_data/when-a-reranker-is-worth-it/preview
social_preview_image: /articles_data/when-a-reranker-is-worth-it/preview/social_preview.jpg
weight: 150
author: Dylan Couzon
author_link: https://www.linkedin.com/in/dcouzon/
date: 2026-08-23 00:00:00+03:00
date: 2026-08-23T00:00:00+03:00
draft: false
keywords:
- cross-encoder reranker
- reranking
- MMR
- search relevance
- FastEmbed
- cross-encoder reranker
- reranking
- MMR
- search relevance
- FastEmbed
partition: learn
learning_kind: guides
aliases:
- /articles/when-a-reranker-is-worth-it/
- /articles/when-a-reranker-is-worth-it/
guide_series: true
---
@@ -1,24 +1,24 @@
---
title: When Your Collection Outgrows RAM
short_description: Keep the quantized copy in RAM and the original vectors on disk, then measure what rescoring reads back on your own deployment.
description: 'Set quantization and memory placement in Qdrant once a collection outgrows RAM: what the rescoring disk read costs and what quality it recovers.'
title: "When Your Collection Outgrows RAM"
short_description: "Keep the quantized copy in RAM and the original vectors on disk, then measure what rescoring reads back on your own deployment."
description: "Set quantization and memory placement in Qdrant once a collection outgrows RAM: what the rescoring disk read costs and what quality it recovers."
preview_dir: /articles_data/when-your-collection-outgrows-ram/preview
social_preview_image: /articles_data/when-your-collection-outgrows-ram/preview/social_preview.jpg
weight: 160
author: Dylan Couzon
author_link: https://www.linkedin.com/in/dcouzon/
date: 2026-08-24 00:00:00+03:00
date: 2026-08-24T00:00:00+03:00
draft: false
keywords:
- memory tiers
- quantization
- rescoring
- oversampling
- TurboQuant
- memory tiers
- quantization
- rescoring
- oversampling
- TurboQuant
partition: learn
learning_kind: guides
aliases:
- /articles/when-your-collection-outgrows-ram/
- /articles/when-your-collection-outgrows-ram/
guide_series: true
---
@@ -5,6 +5,8 @@ description: "Run similarity search in Qdrant to retrieve nearest-neighbor point
weight: 5
cta: "Run your first similarity search. Free, no infrastructure needed."
aliases:
- /articles/batch-vector-search-with-qdrant/
- /blog/batch-vector-search-with-qdrant/
- ../search
- /documentation/concepts/search/
---
@@ -3,6 +3,7 @@ title: Build a Semantic Search API
short_description: "Build a neural semantic search service on Qdrant using sentence-transformer embeddings and a FastAPI search endpoint."
description: "Tutorial: build a neural search service that encodes text with sentence transformers, indexes vectors in Qdrant, and serves results through FastAPI."
aliases:
- /articles/neural-search-tutorial/
- /documentation/tutorials/neural-search/
- /documentation/beginner-tutorials/neural-search/
- /documentation/tutorials-search-engineering/neural-search/
@@ -21,8 +21,8 @@ This tutorial focuses on **ANN recall**: how closely approximate nearest-neighbo
ANN recall measures how closely approximate search matches exact kNN. It's the first of four evaluation layers; each higher layer measures a different property of the retrieval system, with different tools.
- **ANN recall** (this tutorial). Is the approximate index close to exact kNN?
- **Retrieval relevance** ([Measuring Retrieval Relevance](/documentation/improve-search/retrieval-relevance/)). Do the top-k results match query intent?
- **Pipeline output quality** ([Evaluating Pipeline Output Quality](/documentation/improve-search/pipeline-output-quality/)). Does the end-to-end pipeline (retrieval + generator, ranker, or UI) produce the right output?
- **Retrieval relevance** ([Measuring Retrieval Relevance](/documentation/search-quality/retrieval-relevance/)). Do the top-k results match query intent?
- **Pipeline output quality** ([Evaluating Pipeline Output Quality](/documentation/search-quality/pipeline-output-quality/)). Does the end-to-end pipeline (retrieval + generator, ranker, or UI) produce the right output?
- **Business impact**. Do the KPIs the business cares about move? Application-specific, out of scope for these tutorials.
A high score on a higher layer requires acceptable scores on the layers below. Embedding quality (separately measured by benchmarks like [MTEB](https://huggingface.co/spaces/mteb/leaderboard)) sets the ceiling on every downstream metric.
@@ -87,4 +87,4 @@ Wire it into CI and fail the job when recall falls below your target threshold.
## Next Steps
Once ANN recall is on target, continue with [Measuring Retrieval Relevance](/documentation/improve-search/retrieval-relevance/) to check how well those results match user intent.
Once ANN recall is on target, continue with [Measuring Retrieval Relevance](/documentation/search-quality/retrieval-relevance/) to check how well those results match user intent.
+78 -78
View File
@@ -8,90 +8,90 @@ feedback: false
build:
render: always
cascade:
- build:
list: local
publishResources: false
render: never
- build:
list: local
publishResources: false
render: never
content:
- partial: documentation/banners/banner-a
title: Grow as a Search Engineer
description: Make better search decisions, adapt a working example, or understand how Qdrant works beneath the API.
linkDescription: Choose the resource that answers your question today.
cloudButton:
text: Explore Practical Guides
url: /documentation/guides/
localButton:
text: Start with Qdrant Essentials
url: /course/essentials/
- partial: documentation/sections/cards-section
title: Choose How to Learn
description: Each resource serves a different purpose. Start with the one that fits your task.
cardsPartial: documentation/cards/docs-cards
cardsPerRow: 2
cards:
- title: Guides
description: Evaluate search quality, choose embedding models, and plan how your Qdrant application grows.
link:
- partial: documentation/banners/banner-a
title: Grow as a Search Engineer
description: Make better search decisions, adapt a working example, or understand how Qdrant works beneath the API.
linkDescription: Choose the resource that answers your question today.
cloudButton:
text: Explore Practical Guides
url: /documentation/guides/
text: Find Practical Guidance
image:
src: /img/dev-portal-learn/articles.png
alt: ''
- title: Tutorials & Examples
description: Open working code and walkthroughs, then adapt the implementation to your data and application stack.
link:
url: /learn/examples/
text: Browse Tutorials & Examples
image:
src: /img/dev-portal-learn/tutorials.png
alt: ''
- title: Courses
description: Build your understanding through structured lessons and exercises, starting with Qdrant Essentials.
link:
url: /course/
text: Explore Courses
image:
src: /img/dev-portal-learn/courses.png
alt: ''
- title: Articles
description: Examine retrieval experiments and the mechanisms behind Qdrant indexing, storage, and search.
link:
url: /articles/
text: Explore Articles
image:
src: /img/dev-portal-learn/articles.png
alt: ''
- partial: documentation/sections/cards-section
title: Start with Your Task
description: Take a direct path to a common search engineering task.
cardsPartial: documentation/cards/docs-cards
cardsPerRow: 2
cards:
- title: Build Your First Search
description: Start with a small semantic search application and adapt it to your own data.
link:
url: /documentation/tutorials-basics/search-beginners/
text: Open the Example
- title: Evaluate Search Quality
description: Choose an evaluation baseline before changing embeddings, retrieval, or ranking.
link:
url: /documentation/search-quality/
text: Explore Search Evaluation
- title: Prepare for Production
description: Plan tenant growth and large imports around the workload you need to serve.
link:
url: /documentation/production-patterns/
text: Explore Production & Performance
- title: Design and Tune Search
description: Choose embeddings and retrieval strategies, then follow the tuning series to test improvements.
link:
url: /documentation/search-tuning/
text: Explore Search Design & Tuning
localButton:
text: Start with Qdrant Essentials
url: /course/essentials/
- partial: documentation/sections/cards-section
title: Choose How to Learn
description: Each resource serves a different purpose. Start with the one that fits your task.
cardsPartial: documentation/cards/docs-cards
cardsPerRow: 2
cards:
- title: Guides
description: Evaluate search quality, choose embedding models, and plan how your Qdrant application grows.
link:
url: /documentation/guides/
text: Find Practical Guidance
image:
src: /img/dev-portal-learn/articles.png
alt: ""
- title: Tutorials & Examples
description: Open working code and walkthroughs, then adapt the implementation to your data and application stack.
link:
url: /learn/examples/
text: Browse Tutorials & Examples
image:
src: /img/dev-portal-learn/tutorials.png
alt: ""
- title: Courses
description: Build your understanding through structured lessons and exercises, starting with Qdrant Essentials.
link:
url: /course/
text: Explore Courses
image:
src: /img/dev-portal-learn/courses.png
alt: ""
- title: Articles
description: Explore vector search concepts, retrieval research, and the mechanisms behind Qdrant indexing, storage, and search.
link:
url: /articles/
text: Explore Articles
image:
src: /img/dev-portal-learn/articles.png
alt: ""
- partial: documentation/sections/cards-section
title: Start with Your Task
description: Take a direct path to a common search engineering task.
cardsPartial: documentation/cards/docs-cards
cardsPerRow: 2
cards:
- title: Build Your First Search
description: Start with a small semantic search application and adapt it to your own data.
link:
url: /documentation/tutorials-basics/search-beginners/
text: Open the Example
- title: Evaluate Search Quality
description: Choose an evaluation baseline before changing embeddings, retrieval, or ranking.
link:
url: /documentation/search-quality/
text: Explore Search Evaluation
- title: Prepare for Production
description: Plan tenant growth and large imports around the workload you need to serve.
link:
url: /documentation/production-patterns/
text: Explore Production & Performance
- title: Design and Tune Search
description: Choose embeddings and retrieval strategies, then follow the tuning series to test improvements.
link:
url: /documentation/search-tuning/
text: Explore Search Design & Tuning
---
# Learn
Choose Guides for practical decisions, Tutorials & Examples for an implementation, Courses for structured study, or Articles for new evidence and engine mechanisms.
Choose Guides for practical decisions, Tutorials & Examples for an implementation, Courses for structured study, or Articles for concepts, research, and engine mechanisms.
## Read More
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
title: "Articles"
type: delimiter
weight: 100 # Change this weight to change order of sections
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
title: "Courses"
type: delimiter
weight: 200 # Change this weight to change order of sections
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
title: "Tutorials"
type: delimiter
weight: 300 # Change this weight to change order of sections
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
+11 -11
View File
@@ -11,15 +11,15 @@ feedback: false
build:
render: always
content:
- partial: documentation/banners/banner-a
title: Find a Tutorial or Example
description: Search, RAG, recommendations, and operations, with code and walkthroughs you can adapt.
linkDescription: Choose your goal and stack, then open the example or its available notebook.
cloudButton:
text: Build Your First Search
url: /documentation/tutorials-basics/search-beginners/
localButton:
text: Browse Tutorials & Examples
url: '#example-library'
- partial: documentation/examples/catalog
- partial: documentation/banners/banner-a
title: Find a Tutorial or Example
description: Search, RAG, recommendations, and operations, with code and walkthroughs you can adapt.
linkDescription: Choose your goal and stack, then open the example or its available notebook.
cloudButton:
text: Build Your First Search
url: /documentation/tutorials-basics/search-beginners/
localButton:
text: Browse Tutorials & Examples
url: "#example-library"
- partial: documentation/examples/catalog
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/core-concepts
weight: 110
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/data-exploration
weight: 180
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/demos-and-tutorials
weight: 190
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/embedding-research
weight: 160
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/mastering-search
weight: 120
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/production-ops
weight: 140
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/qdrant-internals
weight: 150
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/rag-and-agents
weight: 170
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /articles/search-quality
weight: 130
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /course/beginners
weight: 205
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /course/essentials
weight: 210
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /course/multi-vector-search
weight: 220
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,8 +0,0 @@
---
title: "Retrieval Optimization"
weight: 220
type: external-link
external_url: https://www.deeplearning.ai/short-courses/retrieval-optimization-from-tokenization-to-vector-quantization/
sitemapExclude: true
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /documentation/tutorials-basics
weight: 311
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /documentation/tutorials-develop
weight: 315
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /documentation/tutorials-operations
weight: 314
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /documentation/tutorials-lp-overview
weight: 310
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
@@ -1,11 +0,0 @@
---
#Delimiter files are used to separate the list of documentation pages into sections.
type: reference
reference: /documentation/tutorials-search-engineering
weight: 312
sitemapExclude: True
build:
publishResources: false
render: never
partition: learn
---
+136 -135
View File
@@ -1,309 +1,310 @@
- page: /documentation/tutorials-basics/search-beginners/
goal: Get Started
stack:
- Python
- Cloud Inference
- Python
- Cloud Inference
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/semantic-search-in-5-minutes/semantic_search_in_5_minutes.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/semantic-search-in-5-minutes/semantic_search_in_5_minutes.ipynb
- page: /documentation/tutorials-basics/search-beginners-local/
goal: Get Started
stack:
- Python
- Sentence Transformers
- Python
- Sentence Transformers
- page: /documentation/tutorials-basics/cloud-inference-hybrid-search/
goal: Search Quality
stack:
- Python
- Cloud Inference
- Python
- Cloud Inference
- page: /documentation/tutorials-develop/hybrid-search-fastembed/
goal: Search Quality
stack:
- Python
- FastEmbed
- FastAPI
- Python
- FastEmbed
- FastAPI
resources:
- label: View Code
url: https://github.com/qdrant/qdrant_demo/
- label: View Code
url: https://github.com/qdrant/qdrant_demo/
- page: /documentation/tutorials-basics/reranking-hybrid-search/
goal: Search Quality
stack:
- Python
- FastEmbed
- Python
- FastEmbed
- page: /documentation/tutorials-develop/neural-search/
goal: Get Started
stack:
- Python
- FastAPI
- Python
- FastAPI
resources:
- label: Open Notebook
url: https://colab.research.google.com/drive/1kPktoudAP8Tu8n8l-iVMOQhVmHkWV_L9?usp=sharing
- label: Open Notebook
url: https://colab.research.google.com/drive/1kPktoudAP8Tu8n8l-iVMOQhVmHkWV_L9?usp=sharing
- page: /documentation/tutorials-develop/code-search/
goal: Search Quality
stack:
- Python
- FastEmbed
- Python
- FastEmbed
resources:
- label: Open Notebook
url: https://colab.research.google.com/github/qdrant/examples/blob/master/code-search/code-search.ipynb
- label: Open Notebook
url: https://colab.research.google.com/github/qdrant/examples/blob/master/code-search/code-search.ipynb
- page: /documentation/tutorials-basics/huggingface-datasets/
goal: Data & Filtering
stack:
- Python
- Hugging Face
- Python
- Hugging Face
- page: /documentation/tutorials-develop/async-api/
goal: Operations
stack:
- Python
- Python
- page: /documentation/tutorials-search-engineering/ann-recall/
goal: Search Quality
stack:
- Python
- Web UI
- Python
- Web UI
description: Compare approximate search with exact results, inspect ANN recall in the Web UI, and add a repeatable Python check.
keywords: evaluation index quality hnsw approximate exact recall
- page: /documentation/tutorials-search-engineering/branch-aware-search/
goal: Data & Filtering
stack:
- Python
- Python
keywords: versioned documents branches filters inherited data
- page: /documentation/tutorials-search-engineering/index-dynamic-payloads/
goal: Data & Filtering
stack:
- Python
- Python
keywords: arbitrary dynamic attributes filters payload schema
- page: /documentation/tutorials-search-engineering/multi-representation-search/
goal: Search Quality
stack:
- Python
- FastEmbed
- Python
- FastEmbed
description: Combine title, summary, and chunk vectors in one retrieval pipeline, then compare the effect of each representation.
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/multi-representation-search/multi-representation-search.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/multi-representation-search/multi-representation-search.ipynb
- page: /documentation/tutorials-search-engineering/pdf-retrieval-at-scale/
goal: Multimodal Search
stack:
- Python
- ColPali
- Python
- ColPali
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/pdf-retrieval-at-scale/ColPali_ColQwen2_Tutorial.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/pdf-retrieval-at-scale/ColPali_ColQwen2_Tutorial.ipynb
- page: /documentation/tutorials-search-engineering/using-multivector-representations/
goal: Search Quality
stack:
- Python
- FastEmbed
- Python
- FastEmbed
- page: /documentation/tutorials-search-engineering/using-relevance-feedback/
goal: Search Quality
stack:
- Python
- Python
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/using-relevance-feedback/Customizing_Relevance_Feedback.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/using-relevance-feedback/Customizing_Relevance_Feedback.ipynb
- page: /documentation/tutorials-search-engineering/static-embeddings/
goal: Search Quality
stack:
- Python
- Python
- page: /documentation/tutorials-search-engineering/turbo4-multivector-search/
goal: Search Quality
stack:
- Python
- Python
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/multivector-turbo4/Multivector_Turbo4.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/multivector-turbo4/Multivector_Turbo4.ipynb
- page: /documentation/tutorials-search-engineering/collaborative-filtering/
goal: Recommendations
stack:
- Python
- Python
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/collaborative-filtering/collaborative-filtering.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/collaborative-filtering/collaborative-filtering.ipynb
- page: /documentation/tutorials-operations/embedding-model-migration/
goal: Operations
stack:
- Python
- Python
keywords: replace change embedding models migration serving traffic
- page: /documentation/tutorials-operations/create-snapshot/
goal: Operations
stack:
- Python
- Python
- page: /documentation/tutorials-operations/blue-green-deployment/
goal: Operations
stack:
- Python
- Python
- page: /documentation/tutorials-operations/gpu-accelerated-hnsw-indexing/
goal: Operations
stack:
- Python
- Qdrant Cloud
- Python
- Qdrant Cloud
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/gpu-accelerated-hnsw-indexing/Gpu_Accelerated_HNSW_Indexing.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/gpu-accelerated-hnsw-indexing/Gpu_Accelerated_HNSW_Indexing.ipynb
- page: /documentation/tutorials-operations/incremental-embedding-updates/
goal: Data & Filtering
stack:
- Python
- Python
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/temporal-data-drift/sync_raw_data_to_embeddings.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/temporal-data-drift/sync_raw_data_to_embeddings.ipynb
- page: /documentation/tutorials-operations/large-scale-search/
goal: Operations
stack:
- Python
- Python
resources:
- label: View Code
url: https://github.com/qdrant/laion-400m-benchmark
- label: View Code
url: https://github.com/qdrant/laion-400m-benchmark
- page: /documentation/tutorials-operations/migration/
goal: Operations
stack:
- Migration Tool
- Migration Tool
- page: /documentation/tutorials-operations/prevent-unoptimized-usage/
goal: Operations
stack:
- Python
- Python
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/prevent_unoptimized_usage/prevent_unoptimized.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/prevent_unoptimized_usage/prevent_unoptimized.ipynb
- page: /documentation/tutorials-operations/secure-qdrant/
goal: Operations
stack:
- Docker
- Docker
- page: /documentation/tutorials-operations/time-based-sharding/
goal: Data & Filtering
stack:
- Python
- Python
- page: /documentation/tutorials-build-essentials/rag-deepseek/
goal: RAG & Agents
stack:
- Python
- DeepSeek
- Python
- DeepSeek
resources:
- label: View Notebook
url: https://github.com/qdrant/examples/blob/master/rag-with-qdrant-deepseek/deepseek-qdrant.ipynb
- label: View Notebook
url: https://github.com/qdrant/examples/blob/master/rag-with-qdrant-deepseek/deepseek-qdrant.ipynb
- page: /documentation/tutorials-build-essentials/qdrant-n8n/
goal: RAG & Agents
stack:
- n8n
- page: /documentation/tutorials-build-essentials/multimodal-search/
- n8n
- page: /documentation/tutorials-basics/multimodal-search/
goal: Multimodal Search
stack:
- Python
- LlamaIndex
- Python
- Cohere
- Cloud Inference
resources:
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/multimodal-search/Multimodal_Search_with_LlamaIndex.ipynb
- label: Open Notebook
url: https://githubtocolab.com/qdrant/examples/blob/master/multimodal-search/Multimodal_Search_with_Cohere_and_Cloud_Inference.ipynb
- page: /documentation/tutorials-build-essentials/data-ingestion-beginners/
goal: Data & Filtering
stack:
- Python
- LangChain
- AWS
- Python
- LangChain
- AWS
- page: /documentation/tutorials-build-essentials/agentic-rag-camelai-discord/
goal: RAG & Agents
stack:
- Python
- CAMEL-AI
- Python
- CAMEL-AI
resources:
- label: Open Notebook
url: https://colab.research.google.com/drive/1Ymqzm6ySoyVOekY7fteQBCFCXYiYyHxw#scrollTo=QQZXwzqmNfaS
- label: Open Notebook
url: https://colab.research.google.com/drive/1Ymqzm6ySoyVOekY7fteQBCFCXYiYyHxw#scrollTo=QQZXwzqmNfaS
- page: /documentation/tutorials-build-essentials/video-anomaly-edge-part-1/
goal: Multimodal Search
stack:
- Qdrant Edge
- Twelve Labs
- Qdrant Edge
- Twelve Labs
resources:
- label: View Code
url: https://github.com/qdrant/video-anomaly-edge
- label: View Code
url: https://github.com/qdrant/video-anomaly-edge
- page: /documentation/tutorials-build-essentials/video-anomaly-edge-part-2/
goal: Multimodal Search
stack:
- Qdrant Edge
- Twelve Labs
- Qdrant Edge
- Twelve Labs
resources:
- label: View Code
url: https://github.com/qdrant/video-anomaly-edge
- label: View Code
url: https://github.com/qdrant/video-anomaly-edge
- page: /documentation/tutorials-build-essentials/video-anomaly-edge-part-3/
goal: Multimodal Search
stack:
- Qdrant Edge
- Twelve Labs
- Qdrant Edge
- Twelve Labs
resources:
- label: View Code
url: https://github.com/qdrant/video-anomaly-edge
- label: View Code
url: https://github.com/qdrant/video-anomaly-edge
- page: /documentation/examples/graphrag-qdrant-neo4j/
goal: RAG & Agents
stack:
- Python
- Neo4j
- Python
- Neo4j
resources:
- label: View Code
url: https://github.com/qdrant/examples/blob/master/graphrag_neo4j/graphrag.py
- label: View Code
url: https://github.com/qdrant/examples/blob/master/graphrag_neo4j/graphrag.py
- page: /documentation/examples/hybrid-search-llamaindex-jinaai/
goal: RAG & Agents
stack:
- Python
- LlamaIndex
- Jina
- Python
- LlamaIndex
- Jina
resources:
- label: Open Notebook
url: https://githubtocolab.com/infoslack/qdrant-example/blob/main/HC-demo/HC-DO-LlamaIndex-Jina-v2.ipynb
- label: Open Notebook
url: https://githubtocolab.com/infoslack/qdrant-example/blob/main/HC-demo/HC-DO-LlamaIndex-Jina-v2.ipynb
keywords: PDF documents manuals LlamaIndex Jina RAG
- page: /documentation/examples/Qdrant-DSPy-medicalbot/
goal: RAG & Agents
stack:
- Python
- DSPy
- Python
- DSPy
resources:
- label: View Notebook
url: https://github.com/qdrant/examples/blob/master/DSPy-medical-bot/medical_bot_DSPy_Qdrant.ipynb
- label: View Notebook
url: https://github.com/qdrant/examples/blob/master/DSPy-medical-bot/medical_bot_DSPy_Qdrant.ipynb
- page: /documentation/examples/cohere-rag-connector/
goal: RAG & Agents
stack:
- Python
- Cohere
- Python
- Cohere
- page: /documentation/examples/natural-language-search-oracle-cloud-infrastructure-cohere-langchain/
goal: RAG & Agents
stack:
- LangChain
- Cohere
- Oracle Cloud
- LangChain
- Cohere
- Oracle Cloud
- page: /documentation/examples/rag-chatbot-red-hat-openshift-haystack/
goal: RAG & Agents
stack:
- Haystack
- OpenShift
- Haystack
- OpenShift
- page: /documentation/examples/rag-chatbot-scaleway/
goal: RAG & Agents
stack:
- LangChain
- OpenAI
- Scaleway
- LangChain
- OpenAI
- Scaleway
resources:
- label: View Notebook
url: https://github.com/qdrant/examples/blob/langchain-lcel-rag/langchain-lcel-rag/Langchain-LCEL-RAG-Demo.ipynb
- label: View Notebook
url: https://github.com/qdrant/examples/blob/langchain-lcel-rag/langchain-lcel-rag/Langchain-LCEL-RAG-Demo.ipynb
- page: /documentation/examples/rag-chatbot-vultr-dspy-ollama/
goal: RAG & Agents
stack:
- DSPy
- Ollama
- Vultr
- DSPy
- Ollama
- Vultr
- page: /documentation/examples/rag-contract-management-stackit-aleph-alpha/
goal: RAG & Agents
stack:
- Aleph Alpha
- STACKIT
- Aleph Alpha
- STACKIT
- page: /documentation/examples/rag-customer-support-cohere-airbyte-aws/
goal: RAG & Agents
stack:
- Cohere
- Airbyte
- AWS
- Cohere
- Airbyte
- AWS
- page: /documentation/examples/recommendation-system-ovhcloud/
goal: Recommendations
stack:
- Python
- OVHcloud
- Python
- OVHcloud
resources:
- label: View Notebook
url: https://github.com/infoslack/qdrant-example/blob/main/HC-demo/HC-OVH.ipynb
- label: View Notebook
url: https://github.com/infoslack/qdrant-example/blob/main/HC-demo/HC-OVH.ipynb
@@ -1,3 +0,0 @@
# Articles
Browse current Qdrant articles in [Articles](/articles/index.md).
@@ -2,7 +2,7 @@
Find an implementation by goal and stack. Open the example for its prerequisites and procedure, or use its available code.
{{ range site.Data.examples }}
{{ range hugo.Data.examples }}
{{ $page := site.GetPage .page }}
## {{ .title | default $page.Title }}
@@ -1 +0,0 @@
{{ .Inner }}
+4 -4
View File
@@ -76,11 +76,11 @@
/documentation/tutorials-develop/bulk-upload/* /documentation/manage-data/bulk-upload/:splat 301
# Articles category reorganization (technical articles taxonomy)
/articles/vector-search-manuals/ /articles/search-quality/ 301
/articles/vector-search-manuals/ /documentation/search-tuning/ 301
/articles/machine-learning/ /articles/embedding-research/ 301
/articles/ecosystem/ /articles/ 301
/articles/practicle-examples/ /articles/ 301
/articles/rag-and-genai/ /articles/ 301
/articles/ecosystem/ /articles/demos-and-tutorials/ 301
/articles/practicle-examples/ /articles/demos-and-tutorials/ 301
/articles/rag-and-genai/ /articles/rag-and-agents/ 301
# Unpublished indexing-optimization article superseded by bulk-uploads-in-qdrant
/articles/indexing-optimization/ /documentation/production-patterns/bulk-data-import/ 301
@@ -1,56 +1,97 @@
.example-library {
scroll-margin-top: 7rem;
[hidden] { display: none !important; }
scroll-margin-top: $spacer * 7;
&__filters {
display: flex;
flex-wrap: wrap;
align-items: end;
gap: 1rem;
margin: 1.5rem 0;
> div { flex: 1 1 12rem; }
label { display: block; margin-bottom: .5rem; }
input, select {
gap: $spacer;
margin: $spacer * 1.5 0;
> div {
flex: 1 1 $spacer * 12;
}
label {
display: block;
margin-bottom: $spacer * 0.5;
}
input,
select {
width: 100%;
min-height: 2.75rem;
padding: .65rem;
border: 1px solid $neutral-50;
border-radius: .5rem;
min-height: pxToRem(44);
padding: pxToRem(10);
border: pxToRem(1) solid $neutral-50;
border-radius: $spacer * 0.5;
background: $neutral-10;
color: $neutral-98;
color-scheme: dark;
}
:focus-visible { outline: 2px solid $secondary-blue-50; outline-offset: 3px; }
:focus-visible {
outline: pxToRem(2) solid $secondary-blue-50;
outline-offset: pxToRem(3);
}
}
.docs-card__title a { color: inherit; }
&__stack { font-size: .875rem; margin: 0; }
&__actions { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: auto; }
.docs-card__title a {
color: inherit;
}
&__stack {
margin: 0;
font-size: pxToRem(14);
}
&__actions {
display: flex;
flex-wrap: wrap;
gap: $spacer;
margin-top: auto;
}
[data-theme='light'] & {
input, select { background: $neutral-98; color: $neutral-10; color-scheme: light; }
input,
select {
background: $neutral-98;
color: $neutral-10;
color-scheme: light;
}
}
}
.guide-read-more { margin-bottom: 1.5rem; }
// Leave room for the disclosure arrow when a guide topic wraps.
.guide-topic > summary > a { padding-right: 2.5rem; }
.guide-topic > summary > a {
padding-right: $spacer * 2.5;
}
.guide-series-navigation {
border-top: 1px solid $neutral-50;
margin-top: 2rem;
padding-top: 1rem;
margin-top: $spacer * 2;
padding-top: $spacer;
border-top: pxToRem(1) solid $neutral-50;
&__links {
display: flex;
flex-wrap: wrap;
gap: 1rem 2rem;
a { flex: 1 1 15rem; }
span { display: block; font-size: .875rem; color: $neutral-70; }
gap: $spacer $spacer * 2;
a {
flex: 1 1 $spacer * 15;
}
span {
display: block;
font-size: pxToRem(14);
color: $neutral-70;
}
}
}
.guide-series-label {
list-style: none;
margin: .75rem 0 .25rem;
font-size: .75rem;
margin: $spacer * 0.75 0 $spacer * 0.25;
font-size: pxToRem(12);
font-weight: 600;
color: $neutral-70;
}
@@ -1,11 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex">
<title>Articles - Qdrant</title>
<link rel="canonical" href="{{ .Params.redirect_to | absURL }}">
<meta http-equiv="refresh" content="0; url={{ .Params.redirect_to | absURL }}">
</head>
<body><p>Continue to <a href="{{ .Params.redirect_to }}">Articles</a>.</p></body>
</html>
@@ -7,5 +7,3 @@
{{ $old := "<table>" }}
{{ $new := printf "<table class=\"%s\">" "table mb-5" }}
{{ $contentWithWrappedTables | replaceRE $old $new | safeHTML }}
{{ if eq .Params.learning_kind "guides" }}{{ partial "documentation/guides/series-navigation" . }}{{ end }}
@@ -4,10 +4,8 @@
{{ with $page.Params.preview_dir }}
<div class="post-preview"><img src="{{ . }}/preview.jpg" alt="" loading="lazy" /></div>
{{ end }}
{{ with partial "documentation/articles/topic" $page }}
{{ with site.GetPage (printf "/articles/%s/" .) }}
<span class="post-type-badge">{{ .Title }}</span>
{{ end }}
{{ with site.GetPage (printf "/articles/%s/" $page.Params.category) }}
<span class="post-type-badge">{{ .Title }}</span>
{{ end }}
<h3 class="post-title">{{ $page.Title }}</h3>
<p class="post-description">{{ $page.Params.short_description | default $page.Description }}</p>
@@ -4,10 +4,8 @@
<p class="docs-articles__description">{{ .Description }}</p>
<nav class="docs-articles__topics" aria-label="Article Topics">
<a href="/articles/">All Articles</a>
{{ range (site.GetPage "/articles").Sections.ByWeight }}
{{ if and .Params.isCategoryPage (not .Params.article_collection) (not .Params.hideFromList) }}
<a href="{{ .RelPermalink }}" {{ if eq $.Params.category .Params.category }}aria-current="page"{{ end }}>{{ .Title }}</a>
{{ end }}
{{ range where (site.GetPage "/articles").Sections.ByWeight "Params.isCategoryPage" true }}
<a href="{{ .RelPermalink }}" {{ if eq $.Params.category .Params.category }}aria-current="page"{{ end }}>{{ .Title }}</a>
{{ end }}
</nav>
{{ $paginator := .Paginate (partial "documentation/articles/list" .) 14 }}
@@ -1,32 +1,29 @@
{{ $topics := where (site.GetPage "/articles").Sections.ByWeight "Params.isCategoryPage" true }}
<div class="docs-articles docs-articles__blocks">
<div class="docs-core">
{{ partial "documentation/banners/banner-a" (dict "title" "Articles" "description" "Explore search quality, embedding research, Qdrant internals, and production operations." "linkDescription" "Read experiments, mechanisms, and engineering decisions from the Qdrant team." "cloudButton" (dict "text" "Browse Articles" "url" "#article-topics") "localButton" (dict "text" "Explore Guides" "url" "/documentation/guides/")) }}
{{ partial "documentation/banners/banner-a" (dict "title" "Articles" "description" "Explore vector search concepts, retrieval research, Qdrant internals, and application patterns." "linkDescription" "Read technical explanations, experiments, and engineering decisions from the Qdrant team." "cloudButton" (dict "text" "Browse Articles" "url" "#article-topics") "localButton" (dict "text" "Explore Guides" "url" "/documentation/guides/")) }}
</div>
<nav id="article-topics" class="docs-articles__topics" aria-label="Article Topics">
<span>Browse by Topic</span>
{{ range (site.GetPage "/articles").Sections.ByWeight }}
{{ if and .Params.isCategoryPage (not .Params.article_collection) (not .Params.hideFromList) }}
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
{{ end }}
{{ range $topics }}
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
{{ end }}
</nav>
{{ range slice "/articles/search-quality" "/articles/embedding-research" "/articles/qdrant-internals" "/articles/production-ops" }}
{{ with site.GetPage . }}
<section class="docs-articles__block">
<div class="docs-articles__block-header">
<div>
<h2 class="docs-articles__title">{{ .Title }}</h2>
<p class="docs-articles__description">{{ .Description }}</p>
</div>
<a href="{{ .RelPermalink }}" class="docs-articles__block-link button button_outlined button_sm">Explore {{ .Title }}</a>
{{ range $topics }}
<section class="docs-articles__block">
<div class="docs-articles__block-header">
<div>
<h2 class="docs-articles__title">{{ .Title }}</h2>
<p class="docs-articles__description">{{ .Description }}</p>
</div>
<div class="docs-articles__posts row gy-4">
{{ range first 3 (partial "documentation/articles/list" .) }}
{{ partial "documentation/articles/card" (dict "page" .) }}
{{ end }}
</div>
</section>
{{ end }}
<a href="{{ .RelPermalink }}" class="docs-articles__block-link button button_outlined button_sm">Explore {{ .Title }}</a>
</div>
<div class="docs-articles__posts row gy-4">
{{ range first 3 (partial "documentation/articles/list" .) }}
{{ partial "documentation/articles/card" (dict "page" .) }}
{{ end }}
</div>
</section>
{{ end }}
<aside class="docs-articles__guide-callout">
<div>
@@ -1,10 +1,9 @@
{{ $pages := slice }}
{{ range (site.GetPage "/articles").RegularPages }}
{{ $topic := partial "documentation/articles/topic" . }}
{{ if and $topic (not .Draft) (not .Params.hideFromList) }}
{{ if or (not $.Params.category) (eq $.Params.category $topic) }}
{{ $pages = $pages | append . }}
{{ end }}
{{ end }}
{{ $articles := site.GetPage "/articles" }}
{{ $topics := slice }}
{{ range $articles.Sections }}
{{ if .Params.isCategoryPage }}{{ $topics = $topics | append .Params.category }}{{ end }}
{{ end }}
{{ return (sort $pages "PublishDate" "desc") }}
{{ $pages := where $articles.RegularPages "Params.category" "in" $topics }}
{{ $pages = where $pages "Params.hideFromList" "ne" true }}
{{ with .Params.category }}{{ $pages = where $pages "Params.category" . }}{{ end }}
{{ return $pages.ByPublishDate.Reverse }}
@@ -1,6 +0,0 @@
{{ $settings := (site.GetPage "/articles").Params }}
{{ $topic := .Params.category | default "" }}
{{ with index $settings.category_aliases $topic }}{{ $topic = . }}{{ end }}
{{ with index $settings.category_overrides .RelPermalink }}{{ $topic = . }}{{ end }}
{{ if not (in (slice "search-quality" "embedding-research" "qdrant-internals" "production-ops") $topic) }}{{ $topic = "" }}{{ end }}
{{ return $topic }}
@@ -13,11 +13,6 @@
<li class="docs-breadcrumbs__crumb-separator"></li>
<li class="docs-breadcrumbs__crumb"><a href="/articles/">Articles</a></li>
<li class="docs-breadcrumbs__crumb-separator"></li>
{{ else if and (eq (partial "get-partition.html" (dict "page" .)) "learn") (eq .Section "documentation") }}
<li class="docs-breadcrumbs__crumb"><a href="/learn/">Learn</a></li>
<li class="docs-breadcrumbs__crumb-separator"></li>
<li class="docs-breadcrumbs__crumb"><a href="/learn/examples/">Tutorials &amp; Examples</a></li>
<li class="docs-breadcrumbs__crumb-separator"></li>
{{ else }}
{{ $rellink := "" }}
{{ $paths := (split .RelPermalink "/") }}
@@ -22,11 +22,10 @@
<article class="documentation-article">
<div class="documentation-article__header">
{{ $url := "articles" }}
{{ with partial "documentation/articles/topic" . }}{{ $url = printf "articles/%s" . }}{{ end }}
{{ $back := site.GetPage "/articles" }}
{{ with site.GetPage (printf "/articles/%s/" .Params.category) }}{{ $back = . }}{{ end }}
<a href="/{{ $url }}/" class="documentation-article__header-link">
<a href="{{ $back.RelPermalink }}" class="documentation-article__header-link">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M14.6668 8.00004H1.3335M1.3335 8.00004L6.00016 12.6667M1.3335 8.00004L6.00016 3.33337"
@@ -36,10 +35,8 @@
stroke-linejoin="round"
/>
</svg>
{{ with (.Site.GetPage $url) }}
Back to
{{ .Params.Title }}
{{ end }}
Back to
{{ $back.Title }}
</a>
<h1 class="documentation-article__header-title">{{ .Params.title }}</h1>
<div class="documentation-article__header-about">
@@ -84,6 +81,7 @@
<article class="documentation-article">
{{ partial "article-content.html" . }}
{{ partial "documentation/guides/series-navigation" . }}
</article>
{{ if not (eq .Params.feedback false) }}
@@ -1,6 +1,6 @@
{{ $goals := slice }}
{{ $stacks := slice }}
{{ range site.Data.examples }}
{{ range hugo.Data.examples }}
{{ $goals = $goals | append .goal }}
{{ $stacks = $stacks | append .stack }}
{{ end }}
@@ -28,10 +28,10 @@
</div>
<button type="reset" class="button button_outlined button_sm">Clear Filters</button>
</form>
<p data-example-count role="status" aria-live="polite" aria-atomic="true">{{ len site.Data.examples }} results</p>
<p data-example-count role="status" aria-live="polite" aria-atomic="true">{{ len hugo.Data.examples }} results</p>
<p data-example-empty hidden>No tutorials or examples match these filters. Try a broader term or clear the filters.</p>
<div class="row g-4">
{{ range site.Data.examples }}
{{ range hugo.Data.examples }}
{{ $entry := . }}
{{ $page := site.GetPage .page }}
{{ if not $page }}{{ errorf "Unknown example page %s" .page }}{{ end }}
@@ -56,5 +56,3 @@
{{ end }}
</div>
</section>
{{ $script := resources.Get "js/example-library.js" | js.Build | minify | fingerprint }}
<script src="{{ $script.RelPermalink }}" defer></script>
@@ -22,7 +22,7 @@
{{ $url := . }}
{{ with site.GetPage . }}
{{ $description := .Params.short_description }}
{{ range where site.Data.examples "page" $url }}
{{ range where hugo.Data.examples "page" $url }}
{{ $description = .description | default $description }}
{{ end }}
{{ $examples = $examples | append (dict "title" .Title "description" $description "link" (dict "text" "Open Example" "url" .RelPermalink)) }}
@@ -1,7 +1,7 @@
{{ $current := .RelPermalink }}
{{ $isGuide := eq .Params.learning_kind "guides" }}
{{ $goals := slice }}
{{ range site.Data.examples }}{{ $goals = $goals | append .goal }}{{ end }}
{{ range hugo.Data.examples }}{{ $goals = $goals | append .goal }}{{ end }}
{{ $exampleLinks := slice }}
{{ range sort (uniq $goals) }}
{{ $exampleLinks = $exampleLinks | append (dict "title" . "url" (printf "/learn/examples/?%s" (querify "goal" .)) "goal" . "active" false) }}
@@ -20,18 +20,18 @@
{{ end }}
{{ end }}
{{ $articleLinks := slice }}
{{ range (site.GetPage "/articles").Sections.ByWeight }}
{{ if and .Params.isCategoryPage (not .Params.hideFromList) }}
{{ $active := or (eq .RelPermalink $current) (and (eq $.Section "articles") (eq .Params.category (partial "documentation/articles/topic" $))) }}
{{ $articleLinks = $articleLinks | append (dict "title" .Title "url" .RelPermalink "active" $active) }}
{{ end }}
{{ range where (site.GetPage "/articles").Sections.ByWeight "Params.isCategoryPage" true }}
{{ $active := or (eq .RelPermalink $current) (and (eq $.Section "articles") (eq .Params.category $.Params.category)) }}
{{ $articleLinks = $articleLinks | append (dict "title" .Title "url" .RelPermalink "active" $active) }}
{{ end }}
{{ $courseLinks := slice }}
{{ range (site.GetPage "/course").Sections.ByWeight }}
{{ $courseLinks = $courseLinks | append (dict "title" .Title "url" .RelPermalink) }}
{{ end }}
{{ $items := slice
(dict "title" "Guides" "url" "/documentation/guides/" "active" $isGuide "children" $guideLinks)
(dict "title" "Tutorials & Examples" "url" "/learn/examples/" "active" (eq $current "/learn/examples/") "children" $exampleLinks)
(dict "title" "Courses" "url" "/course/" "active" (eq .Section "course") "children" (slice
(dict "title" "Qdrant Essentials" "url" "/course/essentials/")
(dict "title" "Multivector Search" "url" "/course/multi-vector-search/")))
(dict "title" "Courses" "url" "/course/" "active" (eq .Section "course") "children" $courseLinks)
(dict "title" "Articles" "url" "/articles/" "active" (eq .Section "articles") "children" $articleLinks)
}}
<nav class="docs-menu__links" aria-label="Learning Resources">
@@ -61,7 +61,7 @@
{{ $seriesStarted = true }}
{{ end }}
<li class="docs-menu__links-sub-submenu-item{{ if eq .url $current }} active{{ end }}">
<a href="{{ .url }}" data-guide-link {{ if eq .url $current }}aria-current="page"{{ end }}>{{ .title }}</a>
<a href="{{ .url }}" {{ if eq .url $current }}aria-current="page"{{ end }}>{{ .title }}</a>
</li>
{{ end }}
</ul>
@@ -117,6 +117,11 @@
<script src="{{ $catalogFiltersJs.RelPermalink }}"></script>
{{ end }}
{{ if eq .Layout "examples" }}
{{ $exampleLibraryJs := resources.Get "js/example-library.js" | js.Build | minify | resources.Fingerprint "sha512" }}
<script src="{{ $exampleLibraryJs.RelPermalink }}"></script>
{{ end }}
{{ if eq .Section "industries" }}
{{ $customersJs := resources.Get "js/industries.js" | js.Build | minify | resources.Fingerprint "sha512" }}
<script src="{{ $customersJs.RelPermalink }}"></script>
@@ -1,15 +0,0 @@
<div class="row g-3 guide-read-more">
{{ range split (trim .Inner "\n ") "\n" }}
{{ $line := trim . " " }}
{{ if $line }}
{{ $pattern := `^- \[([^\]]+)\]\(([^)]+)\)\s*(.*)$` }}
{{ if not (findRE $pattern $line) }}{{ errorf "Invalid Read More card: %s" $line }}{{ end }}
{{ $title := replaceRE $pattern "${1}" $line }}
{{ $url := replaceRE $pattern "${2}" $line }}
{{ $description := replaceRE $pattern "${3}" $line | replaceRE `^:\s*` "" }}
{{ if $description }}{{ $description = printf "%s%s" (upper (substr $description 0 1)) (substr $description 1) }}{{ end }}
{{ $description = $.Page.RenderString $description }}
{{ partial "documentation/cards/docs-cards" (dict "cardsPerRow" 2 "card" (dict "title" $title "description" $description "link" (dict "text" "Read More" "url" $url))) }}
{{ end }}
{{ end }}
</div>