mirror of
https://github.com/qdrant/landing_page.git
synced 2026-09-25 14:08:30 +02:00
Shortcode for rendering code snippets from separate markdown files (#1548)
* shortcode for rendering code snippets from separate markdown files * formatted code * fix and readme * semi-automatically extracts snippets from markdown * extract snippets from points.md * extract snippets from vectors.md * extract snippets from payload.md * extract snippets from search.md + fixes * extract snippets from explore.md * extract snippets from hybrid-queries.md + mode query by id into search * extract snippets from filtering.md * extract snippets from storage.md + update outdated info * extract snippets from indexing.md * extract snippets from snapshots.md * extract snippets from guides/optimize.md * extract snippets from guides/multiple-partitions.md + fix aside note * extract snippets from guides/quantization.md * use auto-generated descriptions * order json snippets first --------- Co-authored-by: generall <andrey@vasnetsov.com>
This commit is contained in:
@@ -1,3 +1,44 @@
|
||||
# Index
|
||||
- [Running locally](#running-locally)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Required](#required)
|
||||
- [Needed only for development](#needed-only-for-development)
|
||||
- [Updating npm dependencies via hugo](#updating-npm-dependencies-via-hugo)
|
||||
- [Run](#run)
|
||||
- [Run with drafts](#run-with-drafts)
|
||||
- [Build css from scss](#build-css-from-scss)
|
||||
- [Content Management](#content-management)
|
||||
- [Main Page](#main-page)
|
||||
- [Customers/Partners Logos](#customerspartners-logos)
|
||||
- [Articles](#articles)
|
||||
- [Metadata](#metadata)
|
||||
- [Preview image mechanism](#preview-image-mechanism)
|
||||
- [Article preview](#article-preview)
|
||||
- [Documentation](#documentation)
|
||||
- [Metadata](#metadata-1)
|
||||
- [Preview images for documentation pages](#preview-images-for-documentation-pages)
|
||||
- [Documentation sidebar](#documentation-sidebar)
|
||||
- [Delimiter](#delimiter)
|
||||
- [External link](#external-link)
|
||||
- [Params](#params)
|
||||
- [Blog](#blog)
|
||||
- [Images](#images)
|
||||
- [Important notes](#important-notes)
|
||||
- [Shortcodes 🧩🧩🧩](#shortcodes-)
|
||||
- [Built-in shortcodes](#built-in-shortcodes)
|
||||
- [Custom shortcodes](#custom-shortcodes)
|
||||
- [🧩 Card](#-card)
|
||||
- [🧩 Grid Row](#-grid-row)
|
||||
- [🧩 Banner](#-banner)
|
||||
- [🧩 Code Snippets Widget](#-code-snippets-widget)
|
||||
- [📁 Directory Structure](#-directory-structure)
|
||||
- [▶️ Example Usage](#-example-usage)
|
||||
- [⚙️ Parameters](#-parameters)
|
||||
- [⚠️ Notes](#-notes)
|
||||
- [🚫 Limitations](#-limitations)
|
||||
|
||||
|
||||
|
||||
# Running locally
|
||||
|
||||
## Prerequisites
|
||||
@@ -271,7 +312,7 @@ In the blog post file, you'll see:
|
||||
- If a post has `featured: true` property in the front matter this post will appear in the "Features and News" blog section. Only the last 4 featured posts will be displayed in this section. Featured posts will not appear in the regular post list.
|
||||
- If there are more than 4 `featured: true` posts (where `draft: false`), the oldest post disappears from /blog.
|
||||
|
||||
## Shortcodes
|
||||
## Shortcodes 🧩🧩🧩
|
||||
|
||||
Hugo lets you use built-in and custom shortcodes to simplify the creation of content. Meanwhile, **keep in mind that shortcodes make the content less portable**. If you decide to move the content to another platform, you'll need to rewrite the shortcodes. **Avoid to overuse them.**
|
||||
|
||||
@@ -291,7 +332,7 @@ If you use a shortcode in your markdown file, but it fails to render, check if t
|
||||
|
||||
You can find the list of available shortcodes in the `qdrant-landing/themes/qdrant/layouts/shortcodes` directory.
|
||||
|
||||
#### Card
|
||||
#### 🧩 Card
|
||||
- Card - variant 1
|
||||
|
||||

|
||||
@@ -323,7 +364,7 @@ col="6" >}}
|
||||
{{< /card >}}
|
||||
```
|
||||
|
||||
Options for card shortcode:
|
||||
Parameters for card shortcode:
|
||||
- `title` - required
|
||||
- `link` -required
|
||||
- `image` - optional, default null
|
||||
@@ -333,7 +374,9 @@ Options for card shortcode:
|
||||
|
||||
Card variant 1 is the default; you can optionally change the icon and type, if you use `image` option, you will get variant 2, type and icon will be ignored even if given.
|
||||
|
||||
#### Grid Row
|
||||
<hr>
|
||||
|
||||
#### 🧩 Grid Row
|
||||
|
||||
Cards should be enclosed in a row shortcode if you want to have more than one card in a row.
|
||||
|
||||
@@ -359,7 +402,9 @@ Example:
|
||||
|
||||
Each card will take up half of the row in the example above.
|
||||
|
||||
#### Banner
|
||||
<hr>
|
||||
|
||||
#### 🧩 Banner
|
||||
|
||||

|
||||
|
||||
@@ -370,11 +415,55 @@ Example:
|
||||
{{< /banner >}}
|
||||
```
|
||||
|
||||
Options for banner shortcode:
|
||||
Parameters for banner shortcode:
|
||||
- `link` - required
|
||||
- `cta` - optional, default "Get Started"
|
||||
- `image` - optional, default "/img/rocket.svg"
|
||||
|
||||
<hr>
|
||||
|
||||
#### 🧩 Code Snippets Widget
|
||||
|
||||

|
||||
|
||||
This shortcode renders a code snippets widget from a specified path.
|
||||
Use it when you want to manage code examples as a collection of separate Markdown files.
|
||||
|
||||
##### 📁 Directory Structure
|
||||
Place all code snippets for a single widget into one directory. Each file should be named after the programming language it represents:
|
||||
|
||||
```
|
||||
points-id/
|
||||
├── http.md
|
||||
├── python.md
|
||||
├── go.md
|
||||
```
|
||||
File names are used for sorting. It's recommended to name files according to the language they contain (e.g., python.md, go.md). Sorting is controlled by the order parameter or the snippetsOrder parameter (see below).
|
||||
|
||||
Each file should contain a code snippet in a fenced code block (```).
|
||||
|
||||
##### ▶️ Example Usage
|
||||
``` hugo
|
||||
{{< code-snippet path="/documentation/headless/snippets/points-id/" order="python http go" >}}
|
||||
```
|
||||
|
||||
##### ⚙️ Parameters
|
||||
- `path` (required) – Path to the directory (inside content/) containing the snippet files.
|
||||
- `order` (optional) – Space-separated list of snippet names to display first. Remaining files will be rendered in the order they appear in the directory. Sorting is based on file names (without .md).
|
||||
|
||||
You can also define a global default snippet order using the snippetsOrder parameter in the relevant section’s _index.md.
|
||||
|
||||
##### ⚠️ Notes
|
||||
**Important:** Turn off rendering for the snippets directory if it's not already disabled in its parent section. Otherwise, Hugo will attempt to generate standalone pages for these files.
|
||||
|
||||
You can include multiple snippets in a single Markdown file, but in that case, the order parameter has no effect—they will render in the order they appear in the file.
|
||||
|
||||
##### 🚫 Limitations
|
||||
Snippet files must not contain front matter (---). Each code snippet should be a fenced code block (```).
|
||||
|
||||
The snippetsOrder parameter only works at the section level or deeper. If you're adding snippets to a section for the first time, make sure to define snippetsOrder in that section’s or a child section’s _index.md.
|
||||
|
||||
|
||||
## SEO
|
||||
|
||||
### Structured data (Schema.org, JSON-LD)
|
||||
@@ -419,3 +508,5 @@ If you want to add a new schema, create a new JSON file in the `qdrant-landing/a
|
||||
When use `seo_schema` and `seo_schema_json` together, `seo_schema` will be used additionally to `seo_schema_json` adding the second <script> tag with the `seo_schema` value.
|
||||
|
||||
Use `seo_schema_json` if you want to reuse the same schema for multiple pages to avoid duplication and make it easier to maintain.
|
||||
|
||||
[To Index](#index)
|
||||
@@ -0,0 +1,124 @@
|
||||
"""
|
||||
This script should generate a description for snippets using OpenAI API.
|
||||
|
||||
Given snippet context and snippet code, the script should generate a short description of the snippet.
|
||||
|
||||
Description will be later used for semantic search of snippets.
|
||||
|
||||
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
from typing import List, Tuple
|
||||
from openai import OpenAI
|
||||
|
||||
|
||||
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
||||
|
||||
client = OpenAI(api_key=OPENAI_API_KEY)
|
||||
|
||||
if not OPENAI_API_KEY:
|
||||
raise ValueError("OPENAI_API_KEY is not set")
|
||||
|
||||
|
||||
|
||||
def describe_snippet(context: str, code: str, category: str) -> str:
|
||||
"""
|
||||
Generate a description for a snippet using OpenAI API.
|
||||
"""
|
||||
response = client.chat.completions.create(model="gpt-3.5-turbo",
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a helpful assistant that generates descriptions for code snippets. Ignore the format of the code and focus more on semantic meaning of the code. Don't mention HTTP, JSON or Python in the description."},
|
||||
{"role": "user", "content": f"Category: {category}\n\nContext: {context}\n\nCode: {code}"},
|
||||
])
|
||||
return response.choices[0].message.content
|
||||
|
||||
|
||||
def read_snippet(dir: str) -> Tuple[str, str]:
|
||||
"""
|
||||
Read a snippet from a file.
|
||||
"""
|
||||
|
||||
snippet_path_http = os.path.join(dir, "http.md")
|
||||
snippet_path_python = os.path.join(dir, "python.md")
|
||||
|
||||
if os.path.exists(snippet_path_http):
|
||||
snippet_path = snippet_path_http
|
||||
elif os.path.exists(snippet_path_python):
|
||||
snippet_path = snippet_path_python
|
||||
else:
|
||||
raise ValueError(f"Snippet file not found in {dir}")
|
||||
|
||||
description_path = os.path.join(dir, "_index.md")
|
||||
|
||||
if not os.path.exists(snippet_path) or not os.path.exists(description_path):
|
||||
raise ValueError(f"Snippet or description file not found in {dir}")
|
||||
|
||||
with open(snippet_path, "r") as f:
|
||||
snippet = f.read()
|
||||
|
||||
with open(description_path, "r") as f:
|
||||
description = f.read()
|
||||
|
||||
return snippet, description
|
||||
|
||||
|
||||
def write_description(dir: str):
|
||||
|
||||
description_path = os.path.join(dir, "_description.md")
|
||||
|
||||
if os.path.exists(description_path):
|
||||
print(f"Description already exists in {description_path}")
|
||||
return
|
||||
|
||||
snippet, description = read_snippet(dir)
|
||||
|
||||
category = dir.split("/")[-2:]
|
||||
|
||||
description = describe_snippet(snippet, description, category)
|
||||
|
||||
with open(description_path, "w") as f:
|
||||
f.write(description)
|
||||
|
||||
|
||||
def get_all_snippets_dirs(root_dir: str) -> List[str]:
|
||||
"""
|
||||
Get all snippets dirs in the root directory.
|
||||
|
||||
Find all sub-sub-directories in the root directory.
|
||||
|
||||
"""
|
||||
|
||||
snippets_dirs = []
|
||||
|
||||
for root, dirs, files in os.walk(root_dir):
|
||||
for dir in dirs:
|
||||
|
||||
# Check that `_index.md` file exists in the directory
|
||||
if not os.path.exists(os.path.join(root, dir, "_index.md")):
|
||||
continue
|
||||
|
||||
snippets_dirs.append(os.path.join(root, dir))
|
||||
return snippets_dirs
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function to run the script.
|
||||
"""
|
||||
|
||||
root_dir = "qdrant-landing/content/documentation/headless/snippets/"
|
||||
|
||||
snippets_dirs = get_all_snippets_dirs(root_dir)
|
||||
|
||||
for snippet_dir in snippets_dirs:
|
||||
print(snippet_dir)
|
||||
write_description(snippet_dir)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,296 @@
|
||||
"""
|
||||
A script which reads markdown file and extracts snippets from it into a separate folder
|
||||
grouped by the language and category.
|
||||
|
||||
|
||||
Example.md:
|
||||
|
||||
|
||||
## Create collection with qdrant
|
||||
|
||||
How to create a collection with qdrant:
|
||||
|
||||
|
||||
```http
|
||||
PUT /collections/my_collection
|
||||
{
|
||||
"vector_config": {
|
||||
"size": 1536,
|
||||
"distance": "Cosine"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="my_collection",
|
||||
vectors_config=VectorParams(size=1536, distance="Cosine"),
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
Now, the script should extract the snippets into a separate folder grouped by the language and "category".
|
||||
Category should be asked from the user, it may contain 2 parts - top-level category and sub-category.
|
||||
|
||||
For example: `create-collection/simple-collection`
|
||||
|
||||
This will create a folder `create-collection` and inside it will create a folder `simple-collection`.
|
||||
All snippets should be placed into this folder with names `http.md`, `python.md`, etc.
|
||||
|
||||
Path to the root folder is defined in the `SNIPPETS_ROOT` variable.
|
||||
|
||||
Instead of providing the category, user can skip it, in this case snippets should be ignored.
|
||||
|
||||
If the category is provided, the script should create a folder for the category if it doesn't exist.
|
||||
|
||||
Snippets in the original file should be replaced with the link to the new file, which looks like this:
|
||||
|
||||
```
|
||||
{{< code-snippet path="{SNIPPERS_MD_ROOT}/{CATEGORY}/{SUBCATEGORY}/" >}}
|
||||
```
|
||||
|
||||
"""
|
||||
|
||||
import dataclasses
|
||||
import re
|
||||
import os
|
||||
import argparse
|
||||
from typing import Optional
|
||||
|
||||
|
||||
SNIPPETS_ROOT = "qdrant-landing/content/documentation/headless/snippets/"
|
||||
SNIPPERS_MD_ROOT = "/documentation/headless/snippets"
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Snippet:
|
||||
language: str
|
||||
content: str
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class SnippetsGroup:
|
||||
# Content of the markdown file before the snippets
|
||||
# Up to the first other snippet(excluding) or header(including)
|
||||
context: str
|
||||
raw_content: str
|
||||
snippets: list[Snippet]
|
||||
path: Optional[str] = None
|
||||
|
||||
|
||||
def extract_snippets(markdown_content: str) -> list[SnippetsGroup]:
|
||||
"""
|
||||
Extracts snippets from the markdown content.
|
||||
|
||||
Snippet group is a sequence of code blocks, not separated by other text.
|
||||
Whitespace-only lines between snippets are allowed.
|
||||
"""
|
||||
# Pattern to match code blocks with their language and content
|
||||
pattern = r'```(\w+)\n(.*?)\n```'
|
||||
matches = list(re.finditer(pattern, markdown_content, re.DOTALL))
|
||||
|
||||
if not matches:
|
||||
return []
|
||||
|
||||
# Pattern to match headers
|
||||
header_pattern = r'^#{1,6}\s+.*$'
|
||||
|
||||
groups = []
|
||||
current_group = []
|
||||
current_raw_content = ""
|
||||
|
||||
for i, match in enumerate(matches):
|
||||
if not current_group:
|
||||
# Start a new group
|
||||
current_group = [match]
|
||||
current_raw_content = match.group(0)
|
||||
|
||||
# Find the context for this group
|
||||
# Look for the previous header or snippet
|
||||
start_pos = 0
|
||||
if i > 0:
|
||||
start_pos = matches[i - 1].end()
|
||||
|
||||
# Find the last header before this snippet
|
||||
context_start = start_pos
|
||||
for header_match in re.finditer(header_pattern, markdown_content[start_pos:match.start()], re.MULTILINE):
|
||||
context_start = start_pos + header_match.start()
|
||||
|
||||
context = markdown_content[context_start:match.start()]
|
||||
else:
|
||||
# Check if there's only whitespace between this match and the previous one
|
||||
last_match = matches[i - 1]
|
||||
between_content = markdown_content[last_match.end():match.start()]
|
||||
|
||||
# Check if the content between matches contains only whitespace
|
||||
if re.match(r'^\s*$', between_content):
|
||||
current_raw_content += between_content + match.group(0)
|
||||
current_group.append(match)
|
||||
else:
|
||||
# There's non-whitespace content between matches, finalize current group
|
||||
groups.append(SnippetsGroup(
|
||||
context=context,
|
||||
raw_content=current_raw_content,
|
||||
snippets=[Snippet(language=m.group(1), content=m.group(2)) for m in current_group]
|
||||
))
|
||||
# Start a new group
|
||||
current_group = [match]
|
||||
current_raw_content = match.group(0)
|
||||
|
||||
# Find the context for the new group
|
||||
# Look for the previous header or snippet
|
||||
start_pos = matches[i - 1].end()
|
||||
|
||||
# Find the last header before this snippet
|
||||
context_start = start_pos
|
||||
for header_match in re.finditer(header_pattern, markdown_content[start_pos:match.start()], re.MULTILINE):
|
||||
context_start = start_pos + header_match.start()
|
||||
|
||||
context = markdown_content[context_start:match.start()]
|
||||
|
||||
# Add the last group if it exists
|
||||
if current_group:
|
||||
groups.append(SnippetsGroup(
|
||||
context=context,
|
||||
raw_content=current_raw_content,
|
||||
snippets=[Snippet(language=m.group(1), content=m.group(2)) for m in current_group]
|
||||
))
|
||||
|
||||
return groups
|
||||
|
||||
|
||||
def get_existing_categories() -> list[str]:
|
||||
"""
|
||||
Returns a list of existing categories. List them from the root folder.
|
||||
"""
|
||||
categories = []
|
||||
for file in os.listdir(SNIPPETS_ROOT):
|
||||
if os.path.isdir(os.path.join(SNIPPETS_ROOT, file)):
|
||||
categories.append(file)
|
||||
|
||||
categories.sort()
|
||||
return categories
|
||||
|
||||
|
||||
def get_existing_sub_categories(category: str) -> list[str]:
|
||||
"""
|
||||
Returns a list of existing sub-categories for a given category.
|
||||
"""
|
||||
sub_categories = os.listdir(os.path.join(SNIPPETS_ROOT, category))
|
||||
sub_categories.sort()
|
||||
return sub_categories
|
||||
|
||||
|
||||
def save_snippets(snippets: list[SnippetsGroup]):
|
||||
"""
|
||||
For each snippet:
|
||||
- Show first snippet content
|
||||
- Show all categories which are already created
|
||||
- Skip if category is not provided
|
||||
- Ask user to select one of the categories or create a new one
|
||||
- Create a new folder for the category if it doesn't exist
|
||||
- Ask a sub-category
|
||||
- Create a new folder for the sub-category if it doesn't exist
|
||||
- Save the snippets into the folder
|
||||
"""
|
||||
|
||||
for group in snippets:
|
||||
print("----------------------------")
|
||||
print(group.context)
|
||||
print("")
|
||||
print(group.snippets[0].content)
|
||||
print("----------------------------")
|
||||
|
||||
existing_categories = get_existing_categories()
|
||||
|
||||
print("Existing categories:")
|
||||
for i, category in enumerate(existing_categories):
|
||||
print(f"{i}. {category}")
|
||||
|
||||
category = input("Enter category: ")\
|
||||
|
||||
if category == "":
|
||||
print("Skipping snippet")
|
||||
continue
|
||||
|
||||
if category not in existing_categories:
|
||||
os.makedirs(os.path.join(SNIPPETS_ROOT, category), exist_ok=True)
|
||||
|
||||
existing_sub_categories = get_existing_sub_categories(category)
|
||||
|
||||
print("Existing sub-categories:")
|
||||
for i, sub_category in enumerate(existing_sub_categories):
|
||||
print(f"{i}. {sub_category}")
|
||||
|
||||
sub_category = input("Enter sub-category: ")
|
||||
if sub_category == "":
|
||||
print("Skipping snippet")
|
||||
continue
|
||||
|
||||
sub_category_path = os.path.join(SNIPPETS_ROOT, category, sub_category)
|
||||
|
||||
group.path = os.path.join(SNIPPERS_MD_ROOT, category, sub_category) + "/"
|
||||
|
||||
if sub_category not in existing_sub_categories:
|
||||
os.makedirs(sub_category_path, exist_ok=True)
|
||||
else:
|
||||
overwrite = input(f"Sub-category '{sub_category}' already exists. Do you want to overwrite? (y/N): ")
|
||||
if overwrite.lower() != 'y':
|
||||
print("Skipping snippet")
|
||||
continue
|
||||
|
||||
for snippet in group.snippets:
|
||||
with open(os.path.join(sub_category_path, f"{snippet.language}.md"), "w") as f:
|
||||
# Save snippet in markdown format
|
||||
f.write(f"```{snippet.language}\n")
|
||||
f.write(snippet.content)
|
||||
f.write("\n```\n")
|
||||
|
||||
# Save context into `_index.md` file
|
||||
with open(os.path.join(sub_category_path, "_index.md"), "w") as f:
|
||||
f.write(group.context)
|
||||
|
||||
|
||||
return snippets
|
||||
|
||||
|
||||
def replace_snippets(markdown_content: str, snippets: list[SnippetsGroup]):
|
||||
"""
|
||||
Replaces snippets in the markdown content with the links to the new files.
|
||||
"""
|
||||
for group in snippets:
|
||||
if group.path is None:
|
||||
continue
|
||||
markdown_content = markdown_content.replace(group.raw_content, '{{< code-snippet path="' + group.path + '" >}}')
|
||||
return markdown_content
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Extract code snippets from markdown file.')
|
||||
parser.add_argument('input_file', help='Path to the input markdown file')
|
||||
parser.add_argument('--output', '-o', help='Path to the output file (default: input_file.tmp)')
|
||||
args = parser.parse_args()
|
||||
|
||||
input_file = args.input_file
|
||||
output_file = args.output or f"{input_file}.tmp"
|
||||
|
||||
with open(input_file, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
snippets = extract_snippets(content)
|
||||
snippets = save_snippets(snippets)
|
||||
|
||||
replaced_content = replace_snippets(content, snippets)
|
||||
|
||||
with open(output_file, "w") as f:
|
||||
f.write(replaced_content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable → Regular
+17
-2179
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -21,66 +21,7 @@ For a step-by-step guide on how to use snapshots, see our [tutorial](/documentat
|
||||
|
||||
To create a new snapshot for an existing collection:
|
||||
|
||||
```http
|
||||
POST /collections/{collection_name}/snapshots
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_snapshot(collection_name="{collection_name}")
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createSnapshot("{collection_name}");
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client.create_snapshot("{collection_name}").await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.createSnapshotAsync("{collection_name}").get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateSnapshotAsync("{collection_name}");
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateSnapshot(context.Background(), "{collection_name}")
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/create-collection-snapshot/" >}}
|
||||
|
||||
This is a synchronous operation for which a `tar` archive file will be generated into the `snapshot_path`.
|
||||
|
||||
@@ -88,139 +29,13 @@ This is a synchronous operation for which a `tar` archive file will be generated
|
||||
|
||||
*Available as of v1.0.0*
|
||||
|
||||
```http
|
||||
DELETE /collections/{collection_name}/snapshots/{snapshot_name}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.delete_snapshot(
|
||||
collection_name="{collection_name}", snapshot_name="{snapshot_name}"
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.deleteSnapshot("{collection_name}", "{snapshot_name}");
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::DeleteSnapshotRequestBuilder;
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.delete_snapshot(DeleteSnapshotRequestBuilder::new(
|
||||
"{collection_name}",
|
||||
"{snapshot_name}",
|
||||
))
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.deleteSnapshotAsync("{collection_name}", "{snapshot_name}").get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.DeleteSnapshotAsync(collectionName: "{collection_name}", snapshotName: "{snapshot_name}");
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.DeleteSnapshot(context.Background(), "{collection_name}", "{snapshot_name}")
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/delete-collection-snapshot/" >}}
|
||||
|
||||
## List snapshot
|
||||
|
||||
List of snapshots for a collection:
|
||||
|
||||
```http
|
||||
GET /collections/{collection_name}/snapshots
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.list_snapshots(collection_name="{collection_name}")
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.listSnapshots("{collection_name}");
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client.list_snapshots("{collection_name}").await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.listSnapshotAsync("{collection_name}").get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.ListSnapshotsAsync("{collection_name}");
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.ListSnapshots(context.Background(), "{collection_name}")
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/list-collection-snapshots/" >}}
|
||||
|
||||
## Retrieve snapshot
|
||||
|
||||
@@ -228,15 +43,7 @@ client.ListSnapshots(context.Background(), "{collection_name}")
|
||||
|
||||
To download a specified snapshot from a collection as a file:
|
||||
|
||||
```http
|
||||
GET /collections/{collection_name}/snapshots/{snapshot_name}
|
||||
```
|
||||
|
||||
```shell
|
||||
curl 'http://{qdrant-url}:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.snapshot' \
|
||||
-H 'api-key: ********' \
|
||||
--output 'filename.snapshot'
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/download-collection-snapshot/" >}}
|
||||
|
||||
## Restore snapshot
|
||||
|
||||
@@ -259,33 +66,7 @@ This method of recovery requires the snapshot file to be downloadable from a URL
|
||||
|
||||
To recover from a URL or local file use the [snapshot recovery endpoint](https://api.qdrant.tech/master/api-reference/snapshots/recover-from-snapshot). This endpoint accepts either a URL like `https://example.com` or a [file URI](https://en.wikipedia.org/wiki/File_URI_scheme) like `file:///tmp/snapshot-2022-10-10.snapshot`. If the target collection does not exist, it will be created.
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}/snapshots/recover
|
||||
{
|
||||
"location": "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.shapshot"
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://qdrant-node-2:6333")
|
||||
|
||||
client.recover_snapshot(
|
||||
"{collection_name}",
|
||||
"http://qdrant-node-1:6333/collections/collection_name/snapshots/snapshot-2022-10-10.shapshot",
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.recoverSnapshot("{collection_name}", {
|
||||
location: "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.shapshot",
|
||||
});
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/recover-collection-snapshot-from-url/" >}}
|
||||
|
||||
<aside role="status">When recovering from a URL, the URL must be reachable by the Qdrant node that you are restoring. In Qdrant Cloud, restoring via URL is not supported since all outbound traffic is blocked for security purposes. You may still restore via file URI or via an uploaded file.</aside>
|
||||
|
||||
@@ -343,43 +124,7 @@ broken state.
|
||||
|
||||
To recover from a URL, you specify an additional parameter in the request body:
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}/snapshots/recover
|
||||
{
|
||||
"location": "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.shapshot",
|
||||
"priority": "snapshot"
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://qdrant-node-2:6333")
|
||||
|
||||
client.recover_snapshot(
|
||||
"{collection_name}",
|
||||
"http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.shapshot",
|
||||
priority=models.SnapshotPriority.SNAPSHOT,
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.recoverSnapshot("{collection_name}", {
|
||||
location: "http://qdrant-node-1:6333/collections/{collection_name}/snapshots/snapshot-2022-10-10.shapshot",
|
||||
priority: "snapshot"
|
||||
});
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -X POST 'http://qdrant-node-1:6333/collections/{collection_name}/snapshots/upload?priority=snapshot' \
|
||||
-H 'api-key: ********' \
|
||||
-H 'Content-Type:multipart/form-data' \
|
||||
-F 'snapshot=@/path/to/snapshot-2022-10-10.shapshot'
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/recover-snapshot-with-priority/" >}}
|
||||
|
||||
## Snapshots for the whole storage
|
||||
|
||||
@@ -394,202 +139,23 @@ Qdrant provides a dedicated API for that as well. It is similar to collection-le
|
||||
|
||||
### Create full storage snapshot
|
||||
|
||||
```http
|
||||
POST /snapshots
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_full_snapshot()
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createFullSnapshot();
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client.create_full_snapshot().await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.createFullSnapshotAsync().get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateFullSnapshotAsync();
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateFullSnapshot(context.Background())
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/create-full-snapshot/" >}}
|
||||
|
||||
### Delete full storage snapshot
|
||||
|
||||
*Available as of v1.0.0*
|
||||
|
||||
```http
|
||||
DELETE /snapshots/{snapshot_name}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.delete_full_snapshot(snapshot_name="{snapshot_name}")
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.deleteFullSnapshot("{snapshot_name}");
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client.delete_full_snapshot("{snapshot_name}").await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.deleteFullSnapshotAsync("{snapshot_name}").get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.DeleteFullSnapshotAsync("{snapshot_name}");
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.DeleteFullSnapshot(context.Background(), "{snapshot_name}")
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/delete-full-snapshot/" >}}
|
||||
|
||||
### List full storage snapshots
|
||||
|
||||
```http
|
||||
GET /snapshots
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient("localhost", port=6333)
|
||||
|
||||
client.list_full_snapshots()
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.listFullSnapshots();
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client.list_full_snapshots().await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.listFullSnapshotAsync().get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.ListFullSnapshotsAsync();
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.ListFullSnapshots(context.Background())
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/list-full-snapshots/" >}}
|
||||
|
||||
### Download full storage snapshot
|
||||
|
||||
<aside role="status">Only available through the REST API for the time being.</aside>
|
||||
|
||||
```http
|
||||
GET /snapshots/{snapshot_name}
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/snapshots/download-full-snapshot/" >}}
|
||||
|
||||
## Restore full storage snapshot
|
||||
|
||||
|
||||
@@ -42,116 +42,7 @@ There are two ways to configure the usage of memmap(also known as on-disk) stora
|
||||
*Available as of v1.2.0*
|
||||
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine",
|
||||
"on_disk": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(
|
||||
size=768, distance=models.Distance.COSINE, on_disk=True
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
on_disk: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{CreateCollectionBuilder, Distance, VectorParamsBuilder};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine).on_disk(true)),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
"{collection_name}",
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.setOnDisk(true)
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
"{collection_name}",
|
||||
new VectorParams
|
||||
{
|
||||
Size = 768,
|
||||
Distance = Distance.Cosine,
|
||||
OnDisk = true
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
OnDisk: qdrant.PtrOf(true),
|
||||
}),
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/with-vectors-on-disk/" >}}
|
||||
|
||||
This will create a collection with all vectors immediately stored in memmap storage.
|
||||
This is the recommended way, in case your Qdrant instance operates with fast disks and you are working with large collections.
|
||||
@@ -164,130 +55,7 @@ There are two ways to do this:
|
||||
1. You can set the threshold globally in the [configuration file](/documentation/guides/configuration/). The parameter is called `memmap_threshold` (previously `memmap_threshold_kb`).
|
||||
2. You can set the threshold for each collection separately during [creation](/documentation/concepts/collections/#create-collection) or [update](/documentation/concepts/collections/#update-collection-parameters).
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine"
|
||||
},
|
||||
"optimizers_config": {
|
||||
"memmap_threshold": 20000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE),
|
||||
optimizers_config=models.OptimizersConfigDiff(memmap_threshold=20000),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
},
|
||||
optimizers_config: {
|
||||
memmap_threshold: 20000,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateCollectionBuilder, Distance, OptimizersConfigDiffBuilder, VectorParamsBuilder,
|
||||
};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
|
||||
.optimizers_config(OptimizersConfigDiffBuilder::default().memmap_threshold(20000)),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.CreateCollection;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
import io.qdrant.client.grpc.Collections.VectorsConfig;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
CreateCollection.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setVectorsConfig(
|
||||
VectorsConfig.newBuilder()
|
||||
.setParams(
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.build())
|
||||
.build())
|
||||
.setOptimizersConfig(
|
||||
OptimizersConfigDiff.newBuilder().setMemmapThreshold(20000).build())
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
collectionName: "{collection_name}",
|
||||
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||
optimizersConfig: new OptimizersConfigDiff { MemmapThreshold = 20000 }
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
}),
|
||||
OptimizersConfig: &qdrant.OptimizersConfigDiff{
|
||||
MaxSegmentSize: qdrant.PtrOf(uint64(20000)),
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/with-optimizer-config/" >}}
|
||||
|
||||
The rule of thumb to set the memmap threshold parameter is simple:
|
||||
|
||||
@@ -297,152 +65,14 @@ The rule of thumb to set the memmap threshold parameter is simple:
|
||||
In addition, you can use memmap storage not only for vectors, but also for HNSW index.
|
||||
To enable this, you need to set the `hnsw_config.on_disk` parameter to `true` during collection [creation](/documentation/concepts/collections/#create-a-collection) or [updating](/documentation/concepts/collections/#update-collection-parameters).
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine"
|
||||
},
|
||||
"optimizers_config": {
|
||||
"memmap_threshold": 20000
|
||||
},
|
||||
"hnsw_config": {
|
||||
"on_disk": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE),
|
||||
optimizers_config=models.OptimizersConfigDiff(memmap_threshold=20000),
|
||||
hnsw_config=models.HnswConfigDiff(on_disk=True),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
},
|
||||
optimizers_config: {
|
||||
memmap_threshold: 20000,
|
||||
},
|
||||
hnsw_config: {
|
||||
on_disk: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateCollectionBuilder, Distance, HnswConfigDiffBuilder, OptimizersConfigDiffBuilder,
|
||||
VectorParamsBuilder,
|
||||
};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
|
||||
.optimizers_config(OptimizersConfigDiffBuilder::default().memmap_threshold(20000))
|
||||
.hnsw_config(HnswConfigDiffBuilder::default().on_disk(true)),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.CreateCollection;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.HnswConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
import io.qdrant.client.grpc.Collections.VectorsConfig;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
CreateCollection.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setVectorsConfig(
|
||||
VectorsConfig.newBuilder()
|
||||
.setParams(
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.build())
|
||||
.build())
|
||||
.setOptimizersConfig(
|
||||
OptimizersConfigDiff.newBuilder().setMemmapThreshold(20000).build())
|
||||
.setHnswConfig(HnswConfigDiff.newBuilder().setOnDisk(true).build())
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
collectionName: "{collection_name}",
|
||||
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||
optimizersConfig: new OptimizersConfigDiff { MemmapThreshold = 20000 },
|
||||
hnswConfig: new HnswConfigDiff { OnDisk = true }
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
}),
|
||||
OptimizersConfig: &qdrant.OptimizersConfigDiff{
|
||||
MaxSegmentSize: qdrant.PtrOf(uint64(20000)),
|
||||
},
|
||||
HnswConfig: &qdrant.HnswConfigDiff{
|
||||
OnDisk: qdrant.PtrOf(true),
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/with-vectors-and-hnsw-on-disk/" >}}
|
||||
|
||||
## Payload storage
|
||||
|
||||
Qdrant supports two types of payload storages: InMemory and OnDisk.
|
||||
|
||||
InMemory payload storage is organized in the same way as in-memory vectors.
|
||||
The payload data is loaded into RAM at service startup while disk and [RocksDB](https://rocksdb.org/) are used for persistence only.
|
||||
The payload data is loaded into RAM at service startup while disk and [Gridstore](/articles/gridstore-key-value-storage/) are used for persistence only.
|
||||
This type of storage works quite fast, but it may require a lot of space to keep all the data in RAM, especially if the payload has large values attached - abstracts of text or even images.
|
||||
|
||||
In the case of large payload values, it might be better to use OnDisk payload storage.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,338 +15,16 @@ aliases:
|
||||
|
||||
When an instance is shared between multiple users, you may need to partition vectors by user. This is done so that each user can only access their own vectors and can't see the vectors of other users.
|
||||
|
||||
> ### NOTE
|
||||
>
|
||||
> The key doesn't necessarily need to be named `group_id`. You can choose a name that best suits your data structure and naming conventions.
|
||||
|
||||
1. Add a `group_id` field to each vector in the collection.
|
||||
<aside role="alert">
|
||||
Note: The key doesn't necessarily need to be named <code>group_id</code>. You can choose a name that best suits your data structure and naming conventions.
|
||||
</aside>
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}/points
|
||||
{
|
||||
"points": [
|
||||
{
|
||||
"id": 1,
|
||||
"payload": {"group_id": "user_1"},
|
||||
"vector": [0.9, 0.1, 0.1]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"payload": {"group_id": "user_1"},
|
||||
"vector": [0.1, 0.9, 0.1]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"payload": {"group_id": "user_2"},
|
||||
"vector": [0.1, 0.1, 0.9]
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
client.upsert(
|
||||
collection_name="{collection_name}",
|
||||
points=[
|
||||
models.PointStruct(
|
||||
id=1,
|
||||
payload={"group_id": "user_1"},
|
||||
vector=[0.9, 0.1, 0.1],
|
||||
),
|
||||
models.PointStruct(
|
||||
id=2,
|
||||
payload={"group_id": "user_1"},
|
||||
vector=[0.1, 0.9, 0.1],
|
||||
),
|
||||
models.PointStruct(
|
||||
id=3,
|
||||
payload={"group_id": "user_2"},
|
||||
vector=[0.1, 0.1, 0.9],
|
||||
),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.upsert("{collection_name}", {
|
||||
points: [
|
||||
{
|
||||
id: 1,
|
||||
payload: { group_id: "user_1" },
|
||||
vector: [0.9, 0.1, 0.1],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
payload: { group_id: "user_1" },
|
||||
vector: [0.1, 0.9, 0.1],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
payload: { group_id: "user_2" },
|
||||
vector: [0.1, 0.1, 0.9],
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{PointStruct, UpsertPointsBuilder};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.upsert_points(UpsertPointsBuilder::new(
|
||||
"{collection_name}",
|
||||
vec![
|
||||
PointStruct::new(1, vec![0.9, 0.1, 0.1], [("group_id", "user_1".into())]),
|
||||
PointStruct::new(2, vec![0.1, 0.9, 0.1], [("group_id", "user_1".into())]),
|
||||
PointStruct::new(3, vec![0.1, 0.1, 0.9], [("group_id", "user_2".into())]),
|
||||
],
|
||||
))
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Points.PointStruct;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.upsertAsync(
|
||||
"{collection_name}",
|
||||
List.of(
|
||||
PointStruct.newBuilder()
|
||||
.setId(id(1))
|
||||
.setVectors(vectors(0.9f, 0.1f, 0.1f))
|
||||
.putAllPayload(Map.of("group_id", value("user_1")))
|
||||
.build(),
|
||||
PointStruct.newBuilder()
|
||||
.setId(id(2))
|
||||
.setVectors(vectors(0.1f, 0.9f, 0.1f))
|
||||
.putAllPayload(Map.of("group_id", value("user_1")))
|
||||
.build(),
|
||||
PointStruct.newBuilder()
|
||||
.setId(id(3))
|
||||
.setVectors(vectors(0.1f, 0.1f, 0.9f))
|
||||
.putAllPayload(Map.of("group_id", value("user_2")))
|
||||
.build()))
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.UpsertAsync(
|
||||
collectionName: "{collection_name}",
|
||||
points: new List<PointStruct>
|
||||
{
|
||||
new()
|
||||
{
|
||||
Id = 1,
|
||||
Vectors = new[] { 0.9f, 0.1f, 0.1f },
|
||||
Payload = { ["group_id"] = "user_1" }
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = 2,
|
||||
Vectors = new[] { 0.1f, 0.9f, 0.1f },
|
||||
Payload = { ["group_id"] = "user_1" }
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = 3,
|
||||
Vectors = new[] { 0.1f, 0.1f, 0.9f },
|
||||
Payload = { ["group_id"] = "user_2" }
|
||||
}
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.Upsert(context.Background(), &qdrant.UpsertPoints{
|
||||
CollectionName: "{collection_name}",
|
||||
Points: []*qdrant.PointStruct{
|
||||
{
|
||||
Id: qdrant.NewIDNum(1),
|
||||
Vectors: qdrant.NewVectors(0.9, 0.1, 0.1),
|
||||
Payload: qdrant.NewValueMap(map[string]any{"group_id": "user_1"}),
|
||||
},
|
||||
{
|
||||
Id: qdrant.NewIDNum(2),
|
||||
Vectors: qdrant.NewVectors(0.1, 0.9, 0.1),
|
||||
Payload: qdrant.NewValueMap(map[string]any{"group_id": "user_1"}),
|
||||
},
|
||||
{
|
||||
Id: qdrant.NewIDNum(3),
|
||||
Vectors: qdrant.NewVectors(0.1, 0.1, 0.9),
|
||||
Payload: qdrant.NewValueMap(map[string]any{"group_id": "user_2"}),
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/insert-points/with-tenant-group-id/" >}}
|
||||
|
||||
2. Use a filter along with `group_id` to filter vectors for each user.
|
||||
|
||||
```http
|
||||
POST /collections/{collection_name}/points/query
|
||||
{
|
||||
"query": [0.1, 0.1, 0.9],
|
||||
"filter": {
|
||||
"must": [
|
||||
{
|
||||
"key": "group_id",
|
||||
"match": {
|
||||
"value": "user_1"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"limit": 10
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.query_points(
|
||||
collection_name="{collection_name}",
|
||||
query=[0.1, 0.1, 0.9],
|
||||
query_filter=models.Filter(
|
||||
must=[
|
||||
models.FieldCondition(
|
||||
key="group_id",
|
||||
match=models.MatchValue(
|
||||
value="user_1",
|
||||
),
|
||||
)
|
||||
]
|
||||
),
|
||||
limit=10,
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.query("{collection_name}", {
|
||||
query: [0.1, 0.1, 0.9],
|
||||
filter: {
|
||||
must: [{ key: "group_id", match: { value: "user_1" } }],
|
||||
},
|
||||
limit: 10,
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{Condition, Filter, QueryPointsBuilder};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.query(
|
||||
QueryPointsBuilder::new("{collection_name}")
|
||||
.query(vec![0.1, 0.1, 0.9])
|
||||
.limit(10)
|
||||
.filter(Filter::must([Condition::matches(
|
||||
"group_id",
|
||||
"user_1".to_string(),
|
||||
)])),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import java.util.List;
|
||||
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Points.Filter;
|
||||
import io.qdrant.client.grpc.Points.QueryPoints;
|
||||
|
||||
import static io.qdrant.client.QueryFactory.nearest;
|
||||
import static io.qdrant.client.ConditionFactory.matchKeyword;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.queryAsync(
|
||||
QueryPoints.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setFilter(
|
||||
Filter.newBuilder().addMust(matchKeyword("group_id", "user_1")).build())
|
||||
.setQuery(nearest(0.1f, 0.1f, 0.9f))
|
||||
.setLimit(10)
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
using static Qdrant.Client.Grpc.Conditions;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.QueryAsync(
|
||||
collectionName: "{collection_name}",
|
||||
query: new float[] { 0.1f, 0.1f, 0.9f },
|
||||
filter: MatchKeyword("group_id", "user_1"),
|
||||
limit: 10
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.Query(context.Background(), &qdrant.QueryPoints{
|
||||
CollectionName: "{collection_name}",
|
||||
Query: qdrant.NewQuery(0.1, 0.1, 0.9),
|
||||
Filter: &qdrant.Filter{
|
||||
Must: []*qdrant.Condition{
|
||||
qdrant.NewMatch("group_id", "user_1"),
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/query-points/with-filter-by-group-id/" >}}
|
||||
|
||||
## Calibrate performance
|
||||
|
||||
@@ -359,135 +37,7 @@ To implement this approach, you should:
|
||||
1. Set `payload_m` in the HNSW configuration to a non-zero value, such as 16.
|
||||
2. Set `m` in hnsw config to 0. This will disable building global index for the whole collection.
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine"
|
||||
},
|
||||
"hnsw_config": {
|
||||
"payload_m": 16,
|
||||
"m": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE),
|
||||
hnsw_config=models.HnswConfigDiff(
|
||||
payload_m=16,
|
||||
m=0,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
},
|
||||
hnsw_config: {
|
||||
payload_m: 16,
|
||||
m: 0,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateCollectionBuilder, Distance, HnswConfigDiffBuilder, VectorParamsBuilder,
|
||||
};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
|
||||
.hnsw_config(HnswConfigDiffBuilder::default().payload_m(16).m(0)),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.CreateCollection;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.HnswConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
import io.qdrant.client.grpc.Collections.VectorsConfig;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
CreateCollection.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setVectorsConfig(
|
||||
VectorsConfig.newBuilder()
|
||||
.setParams(
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.build())
|
||||
.build())
|
||||
.setHnswConfig(HnswConfigDiff.newBuilder().setPayloadM(16).setM(0).build())
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
collectionName: "{collection_name}",
|
||||
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||
hnswConfig: new HnswConfigDiff { PayloadM = 16, M = 0 }
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
}),
|
||||
HnswConfig: &qdrant.HnswConfigDiff{
|
||||
PayloadM: qdrant.PtrOf(uint64(16)),
|
||||
M: qdrant.PtrOf(uint64(0)),
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/with-disabled-global-hnsw/" >}}
|
||||
|
||||
3. Create keyword payload index for `group_id` field.
|
||||
|
||||
@@ -496,128 +46,7 @@ client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
</aside>
|
||||
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}/index
|
||||
{
|
||||
"field_name": "group_id",
|
||||
"field_schema": {
|
||||
"type": "keyword",
|
||||
"is_tenant": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
client.create_payload_index(
|
||||
collection_name="{collection_name}",
|
||||
field_name="group_id",
|
||||
field_schema=models.KeywordIndexParams(
|
||||
type="keyword",
|
||||
is_tenant=True,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
client.createPayloadIndex("{collection_name}", {
|
||||
field_name: "group_id",
|
||||
field_schema: {
|
||||
type: "keyword",
|
||||
is_tenant: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateFieldIndexCollectionBuilder,
|
||||
KeywordIndexParamsBuilder,
|
||||
FieldType
|
||||
};
|
||||
use qdrant_client::{Qdrant, QdrantError};
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client.create_field_index(
|
||||
CreateFieldIndexCollectionBuilder::new(
|
||||
"{collection_name}",
|
||||
"group_id",
|
||||
FieldType::Keyword,
|
||||
).field_index_params(
|
||||
KeywordIndexParamsBuilder::default()
|
||||
.is_tenant(true)
|
||||
)
|
||||
).await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.PayloadIndexParams;
|
||||
import io.qdrant.client.grpc.Collections.PayloadSchemaType;
|
||||
import io.qdrant.client.grpc.Collections.KeywordIndexParams;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createPayloadIndexAsync(
|
||||
"{collection_name}",
|
||||
"group_id",
|
||||
PayloadSchemaType.Keyword,
|
||||
PayloadIndexParams.newBuilder()
|
||||
.setKeywordIndexParams(
|
||||
KeywordIndexParams.newBuilder()
|
||||
.setIsTenant(true)
|
||||
.build())
|
||||
.build(),
|
||||
null,
|
||||
null,
|
||||
null)
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreatePayloadIndexAsync(
|
||||
collectionName: "{collection_name}",
|
||||
fieldName: "group_id",
|
||||
schemaType: PayloadSchemaType.Keyword,
|
||||
indexParams: new PayloadIndexParams
|
||||
{
|
||||
KeywordIndexParams = new KeywordIndexParams
|
||||
{
|
||||
IsTenant = true
|
||||
}
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateFieldIndex(context.Background(), &qdrant.CreateFieldIndexCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
FieldName: "group_id",
|
||||
FieldType: qdrant.FieldType_FieldTypeKeyword.Enum(),
|
||||
FieldIndexParams: qdrant.NewPayloadIndexParams(
|
||||
&qdrant.KeywordIndexParams{
|
||||
IsTenant: qdrant.PtrOf(true),
|
||||
}),
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-payload-index/with-group-id-as-tenant/" >}}
|
||||
|
||||
`is_tenant=true` parameter is optional, but specifying it provides storage with additional information about the usage patterns the collection is going to use.
|
||||
When specified, storage structure will be organized in a way to co-locate vectors of the same tenant together, which can significantly improve performance in some cases.
|
||||
|
||||
@@ -27,296 +27,13 @@ To configure in-memory quantization, with on-disk original vectors, you need to
|
||||
- `quantization_config`: Compresses quantized vectors to `int8` using the `scalar` method.
|
||||
- `always_ram`: Keeps quantized vectors in RAM.
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine",
|
||||
"on_disk": true
|
||||
},
|
||||
"quantization_config": {
|
||||
"scalar": {
|
||||
"type": "int8",
|
||||
"always_ram": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE, on_disk=True),
|
||||
quantization_config=models.ScalarQuantization(
|
||||
scalar=models.ScalarQuantizationConfig(
|
||||
type=models.ScalarType.INT8,
|
||||
always_ram=True,
|
||||
),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
on_disk: true,
|
||||
},
|
||||
quantization_config: {
|
||||
scalar: {
|
||||
type: "int8",
|
||||
always_ram: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateCollectionBuilder, Distance, QuantizationType, ScalarQuantizationBuilder,
|
||||
VectorParamsBuilder,
|
||||
};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
|
||||
.quantization_config(
|
||||
ScalarQuantizationBuilder::default()
|
||||
.r#type(QuantizationType::Int8.into())
|
||||
.always_ram(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.CreateCollection;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.QuantizationConfig;
|
||||
import io.qdrant.client.grpc.Collections.QuantizationType;
|
||||
import io.qdrant.client.grpc.Collections.ScalarQuantization;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
import io.qdrant.client.grpc.Collections.VectorsConfig;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
CreateCollection.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setVectorsConfig(
|
||||
VectorsConfig.newBuilder()
|
||||
.setParams(
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.setOnDisk(true)
|
||||
.build())
|
||||
.build())
|
||||
.setQuantizationConfig(
|
||||
QuantizationConfig.newBuilder()
|
||||
.setScalar(
|
||||
ScalarQuantization.newBuilder()
|
||||
.setType(QuantizationType.Int8)
|
||||
.setAlwaysRam(true)
|
||||
.build())
|
||||
.build())
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
collectionName: "{collection_name}",
|
||||
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine, OnDisk = true },
|
||||
quantizationConfig: new QuantizationConfig
|
||||
{
|
||||
Scalar = new ScalarQuantization { Type = QuantizationType.Int8, AlwaysRam = true }
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
OnDisk: qdrant.PtrOf(true),
|
||||
}),
|
||||
QuantizationConfig: qdrant.NewQuantizationScalar(&qdrant.ScalarQuantization{
|
||||
Type: qdrant.QuantizationType_Int8,
|
||||
AlwaysRam: qdrant.PtrOf(true),
|
||||
}),
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/scalar-quantization-in-ram/" >}}
|
||||
|
||||
### Disable Rescoring for Faster Search (optional)
|
||||
|
||||
This is completely optional. Disabling rescoring with search `params` can further reduce the number of disk reads. Note that this might slightly decrease precision.
|
||||
|
||||
```http
|
||||
POST /collections/{collection_name}/points/query
|
||||
{
|
||||
"query": [0.2, 0.1, 0.9, 0.7],
|
||||
"params": {
|
||||
"quantization": {
|
||||
"rescore": false
|
||||
}
|
||||
},
|
||||
"limit": 10
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.query_points(
|
||||
collection_name="{collection_name}",
|
||||
query=[0.2, 0.1, 0.9, 0.7],
|
||||
search_params=models.SearchParams(
|
||||
quantization=models.QuantizationSearchParams(rescore=False)
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.query("{collection_name}", {
|
||||
query: [0.2, 0.1, 0.9, 0.7],
|
||||
params: {
|
||||
quantization: {
|
||||
rescore: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
QuantizationSearchParamsBuilder, QueryPointsBuilder, SearchParamsBuilder,
|
||||
};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.query(
|
||||
QueryPointsBuilder::new("{collection_name}")
|
||||
.query(vec![0.2, 0.1, 0.9, 0.7])
|
||||
.limit(3)
|
||||
.params(
|
||||
SearchParamsBuilder::default()
|
||||
.quantization(QuantizationSearchParamsBuilder::default().rescore(false)),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Points.QuantizationSearchParams;
|
||||
import io.qdrant.client.grpc.Points.QueryPoints;
|
||||
import io.qdrant.client.grpc.Points.SearchParams;
|
||||
|
||||
import static io.qdrant.client.QueryFactory.nearest;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.queryAsync(
|
||||
QueryPoints.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
|
||||
.setParams(
|
||||
SearchParams.newBuilder()
|
||||
.setQuantization(
|
||||
QuantizationSearchParams.newBuilder().setRescore(false).build())
|
||||
.build())
|
||||
.setLimit(3)
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.QueryAsync(
|
||||
collectionName: "{collection_name}",
|
||||
query: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
|
||||
searchParams: new SearchParams
|
||||
{
|
||||
Quantization = new QuantizationSearchParams { Rescore = false }
|
||||
},
|
||||
limit: 3
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.Query(context.Background(), &qdrant.QueryPoints{
|
||||
CollectionName: "{collection_name}",
|
||||
Query: qdrant.NewQuery(0.2, 0.1, 0.9, 0.7),
|
||||
Params: &qdrant.SearchParams{
|
||||
Quantization: &qdrant.QuantizationSearchParams{
|
||||
Rescore: qdrant.PtrOf(true),
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/query-points/disable-quantization-rescoring/" >}}
|
||||
|
||||
## 2. High Precision with Low Memory Usage
|
||||
|
||||
@@ -324,134 +41,7 @@ If you require high precision but have limited RAM, you can store both vectors a
|
||||
|
||||
To store the vectors `on_disk`, you need to configure both the vectors and the HNSW index:
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine",
|
||||
"on_disk": true
|
||||
},
|
||||
"hnsw_config": {
|
||||
"on_disk": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE, on_disk=True),
|
||||
hnsw_config=models.HnswConfigDiff(on_disk=True),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
on_disk: true,
|
||||
},
|
||||
hnsw_config: {
|
||||
on_disk: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateCollectionBuilder, Distance, HnswConfigDiffBuilder, VectorParamsBuilder,
|
||||
};
|
||||
use qdrant_client::{Qdrant, QdrantError};
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine).on_disk(true))
|
||||
.hnsw_config(HnswConfigDiffBuilder::default().on_disk(true)),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.CreateCollection;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.HnswConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
import io.qdrant.client.grpc.Collections.VectorsConfig;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
CreateCollection.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setVectorsConfig(
|
||||
VectorsConfig.newBuilder()
|
||||
.setParams(
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.setOnDisk(true)
|
||||
.build())
|
||||
.build())
|
||||
.setHnswConfig(HnswConfigDiff.newBuilder().setOnDisk(true).build())
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
collectionName: "{collection_name}",
|
||||
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine, OnDisk = true},
|
||||
hnswConfig: new HnswConfigDiff { OnDisk = true }
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
OnDisk: qdrant.PtrOf(true),
|
||||
}),
|
||||
HnswConfig: &qdrant.HnswConfigDiff{
|
||||
OnDisk: qdrant.PtrOf(true),
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/with-vectors-and-hnsw-on-disk/" >}}
|
||||
|
||||
### Improving Precision
|
||||
|
||||
@@ -476,159 +66,7 @@ For scenarios requiring both high speed and high precision, keep as much data in
|
||||
|
||||
Here is how you can configure scalar quantization for a collection:
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine"
|
||||
},
|
||||
"quantization_config": {
|
||||
"scalar": {
|
||||
"type": "int8",
|
||||
"always_ram": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE),
|
||||
quantization_config=models.ScalarQuantization(
|
||||
scalar=models.ScalarQuantizationConfig(
|
||||
type=models.ScalarType.INT8,
|
||||
always_ram=True,
|
||||
),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
},
|
||||
quantization_config: {
|
||||
scalar: {
|
||||
type: "int8",
|
||||
always_ram: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateCollectionBuilder, Distance, QuantizationType, ScalarQuantizationBuilder,
|
||||
VectorParamsBuilder,
|
||||
};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
|
||||
.quantization_config(
|
||||
ScalarQuantizationBuilder::default()
|
||||
.r#type(QuantizationType::Int8.into())
|
||||
.always_ram(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.CreateCollection;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.QuantizationConfig;
|
||||
import io.qdrant.client.grpc.Collections.QuantizationType;
|
||||
import io.qdrant.client.grpc.Collections.ScalarQuantization;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
import io.qdrant.client.grpc.Collections.VectorsConfig;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
CreateCollection.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setVectorsConfig(
|
||||
VectorsConfig.newBuilder()
|
||||
.setParams(
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.build())
|
||||
.build())
|
||||
.setQuantizationConfig(
|
||||
QuantizationConfig.newBuilder()
|
||||
.setScalar(
|
||||
ScalarQuantization.newBuilder()
|
||||
.setType(QuantizationType.Int8)
|
||||
.setAlwaysRam(true)
|
||||
.build())
|
||||
.build())
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
collectionName: "{collection_name}",
|
||||
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine},
|
||||
quantizationConfig: new QuantizationConfig
|
||||
{
|
||||
Scalar = new ScalarQuantization { Type = QuantizationType.Int8, AlwaysRam = true }
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
}),
|
||||
QuantizationConfig: qdrant.NewQuantizationScalar(&qdrant.ScalarQuantization{
|
||||
Type: qdrant.QuantizationType_Int8,
|
||||
AlwaysRam: qdrant.PtrOf(true),
|
||||
}),
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/scalar-quantization-and-vectors-in-ram/" >}}
|
||||
|
||||
### Fine-Tuning Search Parameters
|
||||
|
||||
@@ -638,118 +76,7 @@ You can adjust search parameters like `hnsw_ef` and `exact` to balance between s
|
||||
- `hnsw_ef`: Number of neighbors to visit during search (higher value = better accuracy, slower speed).
|
||||
- `exact`: Set to `true` for exact search, which is slower but more accurate. You can use it to compare results of the search with different `hnsw_ef` values versus the ground truth.
|
||||
|
||||
```http
|
||||
POST /collections/{collection_name}/points/query
|
||||
{
|
||||
"query": [0.2, 0.1, 0.9, 0.7],
|
||||
"params": {
|
||||
"hnsw_ef": 128,
|
||||
"exact": false
|
||||
},
|
||||
"limit": 3
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.query_points(
|
||||
collection_name="{collection_name}",
|
||||
query=[0.2, 0.1, 0.9, 0.7],
|
||||
search_params=models.SearchParams(hnsw_ef=128, exact=False),
|
||||
limit=3,
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.query("{collection_name}", {
|
||||
query: [0.2, 0.1, 0.9, 0.7],
|
||||
params: {
|
||||
hnsw_ef: 128,
|
||||
exact: false,
|
||||
},
|
||||
limit: 3,
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{QueryPointsBuilder, SearchParamsBuilder};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.query(
|
||||
QueryPointsBuilder::new("{collection_name}")
|
||||
.query(vec![0.2, 0.1, 0.9, 0.7])
|
||||
.limit(3)
|
||||
.params(SearchParamsBuilder::default().hnsw_ef(128).exact(false)),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Points.QueryPoints;
|
||||
import io.qdrant.client.grpc.Points.SearchParams;
|
||||
|
||||
import static io.qdrant.client.QueryFactory.nearest;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.queryAsync(
|
||||
QueryPoints.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
|
||||
.setParams(SearchParams.newBuilder().setHnswEf(128).setExact(false).build())
|
||||
.setLimit(3)
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.QueryAsync(
|
||||
collectionName: "{collection_name}",
|
||||
query: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
|
||||
searchParams: new SearchParams { HnswEf = 128, Exact = false },
|
||||
limit: 3
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.Query(context.Background(), &qdrant.QueryPoints{
|
||||
CollectionName: "{collection_name}",
|
||||
Query: qdrant.NewQuery(0.2, 0.1, 0.9, 0.7),
|
||||
Params: &qdrant.SearchParams{
|
||||
HnswEf: qdrant.PtrOf(uint64(128)),
|
||||
Exact: qdrant.PtrOf(false),
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/query-points/with-params/" >}}
|
||||
|
||||
## Balancing Latency and Throughput
|
||||
|
||||
@@ -766,266 +93,16 @@ You can do this by setting the number of segments in the collection to be equal
|
||||
|
||||
In this case, each segment will be processed in parallel, and the final result will be obtained faster.
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine"
|
||||
},
|
||||
"optimizers_config": {
|
||||
"default_segment_number": 16
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE),
|
||||
optimizers_config=models.OptimizersConfigDiff(default_segment_number=16),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
},
|
||||
optimizers_config: {
|
||||
default_segment_number: 16,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateCollectionBuilder, Distance, OptimizersConfigDiffBuilder, VectorParamsBuilder,
|
||||
};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
|
||||
.optimizers_config(
|
||||
OptimizersConfigDiffBuilder::default().default_segment_number(16),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.CreateCollection;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
import io.qdrant.client.grpc.Collections.VectorsConfig;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
CreateCollection.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setVectorsConfig(
|
||||
VectorsConfig.newBuilder()
|
||||
.setParams(
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.build())
|
||||
.build())
|
||||
.setOptimizersConfig(
|
||||
OptimizersConfigDiff.newBuilder().setDefaultSegmentNumber(16).build())
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
collectionName: "{collection_name}",
|
||||
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||
optimizersConfig: new OptimizersConfigDiff { DefaultSegmentNumber = 16 }
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
}),
|
||||
OptimizersConfig: &qdrant.OptimizersConfigDiff{
|
||||
DefaultSegmentNumber: qdrant.PtrOf(uint64(16)),
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/with-high-number-of-segments/" >}}
|
||||
### Maximizing Throughput
|
||||
|
||||
To maximize throughput, configure Qdrant to use as many cores as possible to process multiple requests in parallel.
|
||||
|
||||
To do that, use fewer segments (usually 2) to handle more requests in parallel.
|
||||
To do that, use fewer segments (usually 2) of larger size (default 200Mb per segment) to handle more requests in parallel.
|
||||
|
||||
Large segments benefit from the size of the index and overall smaller number of vector comparisons required to find the nearest neighbors. However, they will require more time to build the HNSW index.
|
||||
|
||||
```http
|
||||
PUT /collections/{collection_name}
|
||||
{
|
||||
"vectors": {
|
||||
"size": 768,
|
||||
"distance": "Cosine"
|
||||
},
|
||||
"optimizers_config": {
|
||||
"default_segment_number": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient, models
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.create_collection(
|
||||
collection_name="{collection_name}",
|
||||
vectors_config=models.VectorParams(size=768, distance=models.Distance.COSINE),
|
||||
optimizers_config=models.OptimizersConfigDiff(default_segment_number=2),
|
||||
)
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.createCollection("{collection_name}", {
|
||||
vectors: {
|
||||
size: 768,
|
||||
distance: "Cosine",
|
||||
},
|
||||
optimizers_config: {
|
||||
default_segment_number: 2,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```rust
|
||||
use qdrant_client::qdrant::{
|
||||
CreateCollectionBuilder, Distance, OptimizersConfigDiffBuilder, VectorParamsBuilder,
|
||||
};
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client
|
||||
.create_collection(
|
||||
CreateCollectionBuilder::new("{collection_name}")
|
||||
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine))
|
||||
.optimizers_config(
|
||||
OptimizersConfigDiffBuilder::default().default_segment_number(2),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import io.qdrant.client.grpc.Collections.CreateCollection;
|
||||
import io.qdrant.client.grpc.Collections.Distance;
|
||||
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
|
||||
import io.qdrant.client.grpc.Collections.VectorParams;
|
||||
import io.qdrant.client.grpc.Collections.VectorsConfig;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client
|
||||
.createCollectionAsync(
|
||||
CreateCollection.newBuilder()
|
||||
.setCollectionName("{collection_name}")
|
||||
.setVectorsConfig(
|
||||
VectorsConfig.newBuilder()
|
||||
.setParams(
|
||||
VectorParams.newBuilder()
|
||||
.setSize(768)
|
||||
.setDistance(Distance.Cosine)
|
||||
.build())
|
||||
.build())
|
||||
.setOptimizersConfig(
|
||||
OptimizersConfigDiff.newBuilder().setDefaultSegmentNumber(2).build())
|
||||
.build())
|
||||
.get();
|
||||
```
|
||||
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using Qdrant.Client.Grpc;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CreateCollectionAsync(
|
||||
collectionName: "{collection_name}",
|
||||
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||
optimizersConfig: new OptimizersConfigDiff { DefaultSegmentNumber = 2 }
|
||||
);
|
||||
```
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
|
||||
CollectionName: "{collection_name}",
|
||||
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
|
||||
Size: 768,
|
||||
Distance: qdrant.Distance_Cosine,
|
||||
}),
|
||||
OptimizersConfig: &qdrant.OptimizersConfigDiff{
|
||||
DefaultSegmentNumber: qdrant.PtrOf(uint64(2)),
|
||||
},
|
||||
})
|
||||
```
|
||||
{{< code-snippet path="/documentation/headless/snippets/create-collection/with-large-segments/" >}}
|
||||
|
||||
## Summary
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
---
|
||||
build:
|
||||
list: never
|
||||
publishResources: false
|
||||
render: never
|
||||
cascade:
|
||||
- build:
|
||||
list: never
|
||||
publishResources: false
|
||||
render: never
|
||||
---
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
snippetsOrder:
|
||||
- json
|
||||
- http
|
||||
- bash
|
||||
- python
|
||||
- typescript
|
||||
- rust
|
||||
- java
|
||||
- csharp
|
||||
- go
|
||||
---
|
||||
+1
@@ -0,0 +1 @@
|
||||
With this code snippet, you can perform batch operations on points like upserting, updating vectors, deleting vectors, setting, overwriting, deleting, and clearing payload data associated with points. The operations include inserting, updating, and deleting points along with their vectors and payload. Each operation is executed in order specified in the request payload.
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
```http
|
||||
POST /collections/{collection_name}/points/batch
|
||||
{
|
||||
"operations": [
|
||||
{
|
||||
"upsert": {
|
||||
"points": [
|
||||
{
|
||||
"id": 1,
|
||||
"vector": [1.0, 2.0, 3.0, 4.0],
|
||||
"payload": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"update_vectors": {
|
||||
"points": [
|
||||
{
|
||||
"id": 1,
|
||||
"vector": [1.0, 2.0, 3.0, 4.0]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"delete_vectors": {
|
||||
"points": [1],
|
||||
"vector": [""]
|
||||
}
|
||||
},
|
||||
{
|
||||
"overwrite_payload": {
|
||||
"payload": {
|
||||
"test_payload": "1"
|
||||
},
|
||||
"points": [1]
|
||||
}
|
||||
},
|
||||
{
|
||||
"set_payload": {
|
||||
"payload": {
|
||||
"test_payload_2": "2",
|
||||
"test_payload_3": "3"
|
||||
},
|
||||
"points": [1]
|
||||
}
|
||||
},
|
||||
{
|
||||
"delete_payload": {
|
||||
"keys": ["test_payload_2"],
|
||||
"points": [1]
|
||||
}
|
||||
},
|
||||
{
|
||||
"clear_payload": {
|
||||
"points": [1]
|
||||
}
|
||||
},
|
||||
{"delete": {"points": [1]}}
|
||||
]
|
||||
}
|
||||
```
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
```java
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.qdrant.client.PointIdFactory.id;
|
||||
import static io.qdrant.client.ValueFactory.value;
|
||||
import static io.qdrant.client.VectorsFactory.vectors;
|
||||
|
||||
import io.qdrant.client.grpc.Points.PointStruct;
|
||||
import io.qdrant.client.grpc.Points.PointVectors;
|
||||
import io.qdrant.client.grpc.Points.PointsIdsList;
|
||||
import io.qdrant.client.grpc.Points.PointsSelector;
|
||||
import io.qdrant.client.grpc.Points.PointsUpdateOperation;
|
||||
import io.qdrant.client.grpc.Points.PointsUpdateOperation.ClearPayload;
|
||||
import io.qdrant.client.grpc.Points.PointsUpdateOperation.DeletePayload;
|
||||
import io.qdrant.client.grpc.Points.PointsUpdateOperation.DeletePoints;
|
||||
import io.qdrant.client.grpc.Points.PointsUpdateOperation.DeleteVectors;
|
||||
import io.qdrant.client.grpc.Points.PointsUpdateOperation.PointStructList;
|
||||
import io.qdrant.client.grpc.Points.PointsUpdateOperation.SetPayload;
|
||||
import io.qdrant.client.grpc.Points.PointsUpdateOperation.UpdateVectors;
|
||||
import io.qdrant.client.grpc.Points.VectorsSelector;
|
||||
|
||||
client
|
||||
.batchUpdateAsync(
|
||||
"{collection_name}",
|
||||
List.of(
|
||||
PointsUpdateOperation.newBuilder()
|
||||
.setUpsert(
|
||||
PointStructList.newBuilder()
|
||||
.addPoints(
|
||||
PointStruct.newBuilder()
|
||||
.setId(id(1))
|
||||
.setVectors(vectors(1.0f, 2.0f, 3.0f, 4.0f))
|
||||
.build())
|
||||
.build())
|
||||
.build(),
|
||||
PointsUpdateOperation.newBuilder()
|
||||
.setUpdateVectors(
|
||||
UpdateVectors.newBuilder()
|
||||
.addPoints(
|
||||
PointVectors.newBuilder()
|
||||
.setId(id(1))
|
||||
.setVectors(vectors(1.0f, 2.0f, 3.0f, 4.0f))
|
||||
.build())
|
||||
.build())
|
||||
.build(),
|
||||
PointsUpdateOperation.newBuilder()
|
||||
.setDeleteVectors(
|
||||
DeleteVectors.newBuilder()
|
||||
.setPointsSelector(
|
||||
PointsSelector.newBuilder()
|
||||
.setPoints(PointsIdsList.newBuilder().addIds(id(1)).build())
|
||||
.build())
|
||||
.setVectors(VectorsSelector.newBuilder().addNames("").build())
|
||||
.build())
|
||||
.build(),
|
||||
PointsUpdateOperation.newBuilder()
|
||||
.setOverwritePayload(
|
||||
SetPayload.newBuilder()
|
||||
.setPointsSelector(
|
||||
PointsSelector.newBuilder()
|
||||
.setPoints(PointsIdsList.newBuilder().addIds(id(1)).build())
|
||||
.build())
|
||||
.putAllPayload(Map.of("test_payload", value(1)))
|
||||
.build())
|
||||
.build(),
|
||||
PointsUpdateOperation.newBuilder()
|
||||
.setSetPayload(
|
||||
SetPayload.newBuilder()
|
||||
.setPointsSelector(
|
||||
PointsSelector.newBuilder()
|
||||
.setPoints(PointsIdsList.newBuilder().addIds(id(1)).build())
|
||||
.build())
|
||||
.putAllPayload(
|
||||
Map.of("test_payload_2", value(2), "test_payload_3", value(3)))
|
||||
.build())
|
||||
.build(),
|
||||
PointsUpdateOperation.newBuilder()
|
||||
.setDeletePayload(
|
||||
DeletePayload.newBuilder()
|
||||
.setPointsSelector(
|
||||
PointsSelector.newBuilder()
|
||||
.setPoints(PointsIdsList.newBuilder().addIds(id(1)).build())
|
||||
.build())
|
||||
.addKeys("test_payload_2")
|
||||
.build())
|
||||
.build(),
|
||||
PointsUpdateOperation.newBuilder()
|
||||
.setClearPayload(
|
||||
ClearPayload.newBuilder()
|
||||
.setPoints(
|
||||
PointsSelector.newBuilder()
|
||||
.setPoints(PointsIdsList.newBuilder().addIds(id(1)).build())
|
||||
.build())
|
||||
.build())
|
||||
.build(),
|
||||
PointsUpdateOperation.newBuilder()
|
||||
.setDeletePoints(
|
||||
DeletePoints.newBuilder()
|
||||
.setPoints(
|
||||
PointsSelector.newBuilder()
|
||||
.setPoints(PointsIdsList.newBuilder().addIds(id(1)).build())
|
||||
.build())
|
||||
.build())
|
||||
.build()))
|
||||
.get();
|
||||
```
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
```python
|
||||
client.batch_update_points(
|
||||
collection_name="{collection_name}",
|
||||
update_operations=[
|
||||
models.UpsertOperation(
|
||||
upsert=models.PointsList(
|
||||
points=[
|
||||
models.PointStruct(
|
||||
id=1,
|
||||
vector=[1.0, 2.0, 3.0, 4.0],
|
||||
payload={},
|
||||
),
|
||||
]
|
||||
)
|
||||
),
|
||||
models.UpdateVectorsOperation(
|
||||
update_vectors=models.UpdateVectors(
|
||||
points=[
|
||||
models.PointVectors(
|
||||
id=1,
|
||||
vector=[1.0, 2.0, 3.0, 4.0],
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
models.DeleteVectorsOperation(
|
||||
delete_vectors=models.DeleteVectors(points=[1], vector=[""])
|
||||
),
|
||||
models.OverwritePayloadOperation(
|
||||
overwrite_payload=models.SetPayload(
|
||||
payload={"test_payload": 1},
|
||||
points=[1],
|
||||
)
|
||||
),
|
||||
models.SetPayloadOperation(
|
||||
set_payload=models.SetPayload(
|
||||
payload={
|
||||
"test_payload_2": 2,
|
||||
"test_payload_3": 3,
|
||||
},
|
||||
points=[1],
|
||||
)
|
||||
),
|
||||
models.DeletePayloadOperation(
|
||||
delete_payload=models.DeletePayload(keys=["test_payload_2"], points=[1])
|
||||
),
|
||||
models.ClearPayloadOperation(clear_payload=models.PointIdsList(points=[1])),
|
||||
models.DeleteOperation(delete=models.PointIdsList(points=[1])),
|
||||
],
|
||||
)
|
||||
```
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
```rust
|
||||
use std::collections::HashMap;
|
||||
|
||||
use qdrant_client::qdrant::{
|
||||
points_update_operation::{
|
||||
ClearPayload, DeletePayload, DeletePoints, DeleteVectors, Operation, OverwritePayload,
|
||||
PointStructList, SetPayload, UpdateVectors,
|
||||
},
|
||||
PointStruct, PointVectors, PointsUpdateOperation, UpdateBatchPointsBuilder, VectorsSelector,
|
||||
};
|
||||
use qdrant_client::Payload;
|
||||
|
||||
client
|
||||
.update_points_batch(
|
||||
UpdateBatchPointsBuilder::new(
|
||||
"{collection_name}",
|
||||
vec![
|
||||
PointsUpdateOperation {
|
||||
operation: Some(Operation::Upsert(PointStructList {
|
||||
points: vec![PointStruct::new(
|
||||
1,
|
||||
vec![1.0, 2.0, 3.0, 4.0],
|
||||
Payload::default(),
|
||||
)],
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
PointsUpdateOperation {
|
||||
operation: Some(Operation::UpdateVectors(UpdateVectors {
|
||||
points: vec![PointVectors {
|
||||
id: Some(1.into()),
|
||||
vectors: Some(vec![1.0, 2.0, 3.0, 4.0].into()),
|
||||
}],
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
PointsUpdateOperation {
|
||||
operation: Some(Operation::DeleteVectors(DeleteVectors {
|
||||
points_selector: Some(vec![1.into()].into()),
|
||||
vectors: Some(VectorsSelector {
|
||||
names: vec!["".into()],
|
||||
}),
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
PointsUpdateOperation {
|
||||
operation: Some(Operation::OverwritePayload(OverwritePayload {
|
||||
points_selector: Some(vec![1.into()].into()),
|
||||
payload: HashMap::from([("test_payload".to_string(), 1.into())]),
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
PointsUpdateOperation {
|
||||
operation: Some(Operation::SetPayload(SetPayload {
|
||||
points_selector: Some(vec![1.into()].into()),
|
||||
payload: HashMap::from([
|
||||
("test_payload_2".to_string(), 2.into()),
|
||||
("test_payload_3".to_string(), 3.into()),
|
||||
]),
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
PointsUpdateOperation {
|
||||
operation: Some(Operation::DeletePayload(DeletePayload {
|
||||
points_selector: Some(vec![1.into()].into()),
|
||||
keys: vec!["test_payload_2".to_string()],
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
PointsUpdateOperation {
|
||||
operation: Some(Operation::ClearPayload(ClearPayload {
|
||||
points: Some(vec![1.into()].into()),
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
PointsUpdateOperation {
|
||||
operation: Some(Operation::DeletePoints(DeletePoints {
|
||||
points: Some(vec![1.into()].into()),
|
||||
..Default::default()
|
||||
})),
|
||||
},
|
||||
],
|
||||
)
|
||||
.wait(true),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
```typescript
|
||||
client.batchUpdate("{collection_name}", {
|
||||
operations: [
|
||||
{
|
||||
upsert: {
|
||||
points: [
|
||||
{
|
||||
id: 1,
|
||||
vector: [1.0, 2.0, 3.0, 4.0],
|
||||
payload: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
update_vectors: {
|
||||
points: [
|
||||
{
|
||||
id: 1,
|
||||
vector: [1.0, 2.0, 3.0, 4.0],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
delete_vectors: {
|
||||
points: [1],
|
||||
vector: [""],
|
||||
},
|
||||
},
|
||||
{
|
||||
overwrite_payload: {
|
||||
payload: {
|
||||
test_payload: 1,
|
||||
},
|
||||
points: [1],
|
||||
},
|
||||
},
|
||||
{
|
||||
set_payload: {
|
||||
payload: {
|
||||
test_payload_2: 2,
|
||||
test_payload_3: 3,
|
||||
},
|
||||
points: [1],
|
||||
},
|
||||
},
|
||||
{
|
||||
delete_payload: {
|
||||
keys: ["test_payload_2"],
|
||||
points: [1],
|
||||
},
|
||||
},
|
||||
{
|
||||
clear_payload: {
|
||||
points: [1],
|
||||
},
|
||||
},
|
||||
{
|
||||
delete: {
|
||||
points: [1],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
This code snippet demonstrates a feature to check if a collection exists by making a GET request to a specified endpoint that includes the collection name. This functionality is available starting from version 1.8.0.
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```bash
|
||||
curl -X GET http://localhost:6333/collections/{collection_name}/exists
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```csharp
|
||||
await client.CollectionExistsAsync("{collection_name}");
|
||||
```
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
```go
|
||||
import "context"
|
||||
|
||||
client.CollectionExists(context.Background(), "my_collection")
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```http
|
||||
GET http://localhost:6333/collections/{collection_name}/exists
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```java
|
||||
client.collectionExistsAsync("{collection_name}").get();
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```python
|
||||
client.collection_exists(collection_name="{collection_name}")
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```rust
|
||||
client.collection_exists("{collection_name}").await?;
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```typescript
|
||||
client.collectionExists("{collection_name}");
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
This code snippet demonstrates a functionality to clear payload keys from specific points by providing a list of point identifiers.
|
||||
@@ -0,0 +1,7 @@
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.ClearPayloadAsync(collectionName: "{collection_name}", ids: new ulong[] { 0, 3, 100 });
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.ClearPayload(context.Background(), &qdrant.ClearPayloadPoints{
|
||||
CollectionName: "{collection_name}",
|
||||
Points: qdrant.NewPointsSelector(
|
||||
qdrant.NewIDNum(0),
|
||||
qdrant.NewIDNum(3)),
|
||||
})
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
```http
|
||||
POST /collections/{collection_name}/points/payload/clear
|
||||
{
|
||||
"points": [0, 3, 100]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
```java
|
||||
import java.util.List;
|
||||
|
||||
import static io.qdrant.client.PointIdFactory.id;
|
||||
|
||||
client
|
||||
.clearPayloadAsync("{collection_name}", List.of(id(0), id(3), id(100)), true, null, null)
|
||||
.get();
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
```python
|
||||
client.clear_payload(
|
||||
collection_name="{collection_name}",
|
||||
points_selector=[0, 3, 100],
|
||||
)
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
```rust
|
||||
use qdrant_client::qdrant::{ClearPayloadPointsBuilder, PointsIdsList};
|
||||
|
||||
client
|
||||
.clear_payload(
|
||||
ClearPayloadPointsBuilder::new("{collection_name}")
|
||||
.points(PointsIdsList {
|
||||
ids: vec![0.into(), 3.into(), 10.into()],
|
||||
})
|
||||
.wait(true),
|
||||
)
|
||||
.await?;
|
||||
```
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
```typescript
|
||||
client.clearPayload("{collection_name}", {
|
||||
points: [0, 3, 100],
|
||||
});
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
This code snippet creates an alias named "production_collection" for the collection called "example_collection".
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
```bash
|
||||
curl -X POST http://localhost:6333/collections/aliases \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"actions": [
|
||||
{
|
||||
"create_alias": {
|
||||
"collection_name": "example_collection",
|
||||
"alias_name": "production_collection"
|
||||
}
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```csharp
|
||||
await client.CreateAliasAsync(aliasName: "production_collection", collectionName: "example_collection");
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
```go
|
||||
import "context"
|
||||
|
||||
client.CreateAlias(context.Background(), "production_collection", "example_collection")
|
||||
```
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
```http
|
||||
POST /collections/aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"create_alias": {
|
||||
"collection_name": "example_collection",
|
||||
"alias_name": "production_collection"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```java
|
||||
client.createAliasAsync("production_collection", "example_collection").get();
|
||||
```
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
```python
|
||||
client.update_collection_aliases(
|
||||
change_aliases_operations=[
|
||||
models.CreateAliasOperation(
|
||||
create_alias=models.CreateAlias(
|
||||
collection_name="example_collection", alias_name="production_collection"
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
```
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
```rust
|
||||
use qdrant_client::qdrant::CreateAliasBuilder;
|
||||
|
||||
client
|
||||
.create_alias(CreateAliasBuilder::new(
|
||||
"example_collection",
|
||||
"production_collection",
|
||||
))
|
||||
.await?;
|
||||
```
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
```typescript
|
||||
client.updateCollectionAliases({
|
||||
actions: [
|
||||
{
|
||||
create_alias: {
|
||||
collection_name: "example_collection",
|
||||
alias_name: "production_collection",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
This code snippet is aiming to perform an action of removing an alias named "production_collection" within a collection alias in a system.
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
```bash
|
||||
curl -X POST http://localhost:6333/collections/aliases \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"actions": [
|
||||
{
|
||||
"delete_alias": {
|
||||
"alias_name": "production_collection"
|
||||
}
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```csharp
|
||||
await client.DeleteAliasAsync("production_collection");
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
```go
|
||||
import "context"
|
||||
|
||||
client.DeleteAlias(context.Background(), "production_collection")
|
||||
```
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
```http
|
||||
POST /collections/aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"delete_alias": {
|
||||
"alias_name": "production_collection"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```java
|
||||
client.deleteAliasAsync("production_collection").get();
|
||||
```
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
```python
|
||||
client.update_collection_aliases(
|
||||
change_aliases_operations=[
|
||||
models.DeleteAliasOperation(
|
||||
delete_alias=models.DeleteAlias(alias_name="production_collection")
|
||||
),
|
||||
]
|
||||
)
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```rust
|
||||
client.delete_alias("production_collection").await?;
|
||||
```
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
```typescript
|
||||
client.updateCollectionAliases({
|
||||
actions: [
|
||||
{
|
||||
delete_alias: {
|
||||
alias_name: "production_collection",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
This code snippet is used to retrieve all aliases from a collection.
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```bash
|
||||
curl -X GET http://localhost:6333/aliases
|
||||
```
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.ListAliasesAsync();
|
||||
```
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.ListAliases(context.Background())
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```http
|
||||
GET /aliases
|
||||
```
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.listAliasesAsync().get();
|
||||
```
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.get_aliases()
|
||||
```
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
```rust
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client.list_aliases().await?;
|
||||
```
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.getAliases();
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
This code retrieves a list of aliases associated with a specific collection.
|
||||
@@ -0,0 +1,3 @@
|
||||
```bash
|
||||
curl -X GET http://localhost:6333/collections/{collection_name}/aliases
|
||||
```
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.ListCollectionAliasesAsync("{collection_name}");
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.ListCollectionAliases(context.Background(), "{collection_name}")
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
```http
|
||||
GET /collections/{collection_name}/aliases
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
```java
|
||||
import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
|
||||
QdrantClient client =
|
||||
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
|
||||
|
||||
client.listCollectionAliasesAsync("{collection_name}").get();
|
||||
```
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
client.get_collection_aliases(collection_name="{collection_name}")
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
```rust
|
||||
use qdrant_client::Qdrant;
|
||||
|
||||
let client = Qdrant::from_url("http://localhost:6334").build()?;
|
||||
|
||||
client.list_collection_aliases("{collection_name}").await?;
|
||||
```
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
```typescript
|
||||
import { QdrantClient } from "@qdrant/js-client-rest";
|
||||
|
||||
const client = new QdrantClient({ host: "localhost", port: 6333 });
|
||||
|
||||
client.getCollectionAliases("{collection_name}");
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
Perform atomic alias actions to switch collections. In this scenario, there is a POST request made to manage aliases. The code snippet demonstrates a sequence of actions where an alias named "production_collection" is deleted, and then a new alias with the same name is created for the "example_collection". This allows for switching between collections efficiently.
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
```bash
|
||||
curl -X POST http://localhost:6333/collections/aliases \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"actions": [
|
||||
{
|
||||
"delete_alias": {
|
||||
"alias_name": "production_collection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"create_alias": {
|
||||
"collection_name": "example_collection",
|
||||
"alias_name": "production_collection"
|
||||
}
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
```csharp
|
||||
await client.DeleteAliasAsync("production_collection");
|
||||
await client.CreateAliasAsync(aliasName: "production_collection", collectionName: "example_collection");
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
```go
|
||||
import "context"
|
||||
|
||||
client.DeleteAlias(context.Background(), "production_collection")
|
||||
client.CreateAlias(context.Background(), "production_collection", "example_collection")
|
||||
```
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
```http
|
||||
POST /collections/aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"delete_alias": {
|
||||
"alias_name": "production_collection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"create_alias": {
|
||||
"collection_name": "example_collection",
|
||||
"alias_name": "production_collection"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
```java
|
||||
client.deleteAliasAsync("production_collection").get();
|
||||
client.createAliasAsync("production_collection", "example_collection").get();
|
||||
```
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
```python
|
||||
client.update_collection_aliases(
|
||||
change_aliases_operations=[
|
||||
models.DeleteAliasOperation(
|
||||
delete_alias=models.DeleteAlias(alias_name="production_collection")
|
||||
),
|
||||
models.CreateAliasOperation(
|
||||
create_alias=models.CreateAlias(
|
||||
collection_name="example_collection", alias_name="production_collection"
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
```
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
```rust
|
||||
use qdrant_client::qdrant::CreateAliasBuilder;
|
||||
|
||||
client.delete_alias("production_collection").await?;
|
||||
client
|
||||
.create_alias(CreateAliasBuilder::new(
|
||||
"example_collection",
|
||||
"production_collection",
|
||||
))
|
||||
.await?;
|
||||
```
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
```typescript
|
||||
client.updateCollectionAliases({
|
||||
actions: [
|
||||
{
|
||||
delete_alias: {
|
||||
alias_name: "production_collection",
|
||||
},
|
||||
},
|
||||
{
|
||||
create_alias: {
|
||||
collection_name: "example_collection",
|
||||
alias_name: "production_collection",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
This code snippet showcases a feature where you can retrieve information about an existing collection in order to understand how the points are distributed and indexed within it.
|
||||
@@ -0,0 +1,3 @@
|
||||
```bash
|
||||
curl -X GET http://localhost:6333/collections/{collection_name}
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```csharp
|
||||
await client.GetCollectionInfoAsync("{collection_name}");
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
```go
|
||||
import "context"
|
||||
|
||||
client.GetCollectionInfo(context.Background(), "{collection_name}")
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
```http
|
||||
GET /collections/{collection_name}
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
```java
|
||||
client.getCollectionInfoAsync("{collection_name}").get();
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```python
|
||||
client.get_collection(collection_name="{collection_name}")
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
```rust
|
||||
client.collection_info("{collection_name}").await?;
|
||||
```
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
```typescript
|
||||
client.getCollection("{collection_name}");
|
||||
```
|
||||
+1
@@ -0,0 +1 @@
|
||||
This code snippet demonstrates a POST request to count points based on specific filter conditions within a collection. The filter criteria include checking for points with a key "color" that matches the value "red" precisely. By setting the "exact" parameter to true, the count will consider only exact matches. This functionality is helpful for scenarios such as evaluating result sizes for faceted search, determining pagination numbers, and debugging query performance.
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
```csharp
|
||||
using Qdrant.Client;
|
||||
using static Qdrant.Client.Grpc.Conditions;
|
||||
|
||||
var client = new QdrantClient("localhost", 6334);
|
||||
|
||||
await client.CountAsync(
|
||||
collectionName: "{collection_name}",
|
||||
filter: MatchKeyword("color", "red"),
|
||||
exact: true
|
||||
);
|
||||
```
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
client, err := qdrant.NewClient(&qdrant.Config{
|
||||
Host: "localhost",
|
||||
Port: 6334,
|
||||
})
|
||||
|
||||
client.Count(context.Background(), &qdrant.CountPoints{
|
||||
CollectionName: "midlib",
|
||||
Filter: &qdrant.Filter{
|
||||
Must: []*qdrant.Condition{
|
||||
qdrant.NewMatch("color", "red"),
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
```http
|
||||
POST /collections/{collection_name}/points/count
|
||||
{
|
||||
"filter": {
|
||||
"must": [
|
||||
{
|
||||
"key": "color",
|
||||
"match": {
|
||||
"value": "red"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"exact": true
|
||||
}
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user