chub-dev 0.1.0 → 0.1.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,1653 @@
1
+ ---
2
+ name: vector-search
3
+ description: "Qdrant Python Client — use qdrant-client for vector database operations in Python"
4
+ metadata:
5
+ languages: "python"
6
+ versions: "1.15.1"
7
+ updated-on: "2026-03-02"
8
+ source: maintainer
9
+ tags: "qdrant,vector-search,embeddings,similarity,ai"
10
+ ---
11
+
12
+ # Qdrant Python Client v1.15.1
13
+
14
+ ## Golden Rule
15
+
16
+ **Always use `qdrant-client` for Qdrant vector database operations in Python.**
17
+
18
+ Install with:
19
+ ```bash
20
+ pip install qdrant-client
21
+ ```
22
+
23
+ For FastEmbed integration (automatic embedding generation):
24
+ ```bash
25
+ pip install 'qdrant-client[fastembed]'
26
+ ```
27
+
28
+ **Do NOT use:**
29
+ - Outdated or unmaintained Qdrant Python packages
30
+ - Direct REST API calls when the client library provides methods
31
+
32
+ The official `qdrant-client` provides both synchronous and asynchronous interfaces, gRPC support, and built-in FastEmbed integration.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ # Basic installation
38
+ pip install qdrant-client
39
+
40
+ # With FastEmbed support
41
+ pip install 'qdrant-client[fastembed]'
42
+
43
+ # Or using uv
44
+ uv pip install qdrant-client
45
+ ```
46
+
47
+ ## Initialization
48
+
49
+ ### In-Memory Client
50
+
51
+ ```python
52
+ from qdrant_client import QdrantClient
53
+
54
+ # In-memory instance (no persistence)
55
+ client = QdrantClient(":memory:")
56
+ ```
57
+
58
+ ### Local Persistent Storage
59
+
60
+ ```python
61
+ from qdrant_client import QdrantClient
62
+
63
+ # Persistent local storage
64
+ client = QdrantClient(path="./qdrant_data")
65
+ ```
66
+
67
+ ### Remote Server
68
+
69
+ ```python
70
+ from qdrant_client import QdrantClient
71
+
72
+ # Connect to Qdrant server
73
+ client = QdrantClient(host="localhost", port=6333)
74
+
75
+ # Alternative using URL
76
+ client = QdrantClient(url="http://localhost:6333")
77
+ ```
78
+
79
+ ### Qdrant Cloud
80
+
81
+ ```python
82
+ from qdrant_client import QdrantClient
83
+
84
+ # Connect to Qdrant Cloud
85
+ client = QdrantClient(
86
+ url="https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.us-east-0-1.aws.cloud.qdrant.io",
87
+ api_key="your-api-key-here"
88
+ )
89
+ ```
90
+
91
+ ### With Environment Variables
92
+
93
+ ```python
94
+ import os
95
+ from qdrant_client import QdrantClient
96
+
97
+ client = QdrantClient(
98
+ url=os.getenv("QDRANT_URL", "http://localhost:6333"),
99
+ api_key=os.getenv("QDRANT_API_KEY")
100
+ )
101
+ ```
102
+
103
+ ### gRPC Configuration
104
+
105
+ ```python
106
+ from qdrant_client import QdrantClient
107
+
108
+ # Use gRPC for better performance
109
+ client = QdrantClient(
110
+ host="localhost",
111
+ grpc_port=6334,
112
+ prefer_grpc=True
113
+ )
114
+ ```
115
+
116
+ ### Async Client
117
+
118
+ ```python
119
+ from qdrant_client import AsyncQdrantClient
120
+
121
+ # Async client initialization
122
+ async_client = AsyncQdrantClient(
123
+ url="http://localhost:6333"
124
+ )
125
+
126
+ # Use with async/await
127
+ async def main():
128
+ collections = await async_client.get_collections()
129
+ print(collections)
130
+ ```
131
+
132
+ ## Collections
133
+
134
+ ### List Collections
135
+
136
+ ```python
137
+ collections = client.get_collections()
138
+ print(collections.collections)
139
+ ```
140
+
141
+ ### Check Collection Exists
142
+
143
+ ```python
144
+ exists = client.collection_exists("my_collection")
145
+ print(f"Collection exists: {exists}")
146
+ ```
147
+
148
+ ### Create Collection - Single Vector
149
+
150
+ ```python
151
+ from qdrant_client.models import Distance, VectorParams
152
+
153
+ client.create_collection(
154
+ collection_name="my_collection",
155
+ vectors_config=VectorParams(size=384, distance=Distance.COSINE)
156
+ )
157
+ ```
158
+
159
+ ### Distance Metrics
160
+
161
+ ```python
162
+ from qdrant_client.models import Distance
163
+
164
+ # Available distance metrics:
165
+ # Distance.COSINE - Cosine similarity
166
+ # Distance.EUCLID - Euclidean distance
167
+ # Distance.DOT - Dot product
168
+ # Distance.MANHATTAN - Manhattan distance
169
+ ```
170
+
171
+ ### Create Collection - Named Vectors
172
+
173
+ ```python
174
+ from qdrant_client.models import Distance, VectorParams
175
+
176
+ client.create_collection(
177
+ collection_name="multi_vector_collection",
178
+ vectors_config={
179
+ "image": VectorParams(size=512, distance=Distance.DOT),
180
+ "text": VectorParams(size=384, distance=Distance.COSINE)
181
+ }
182
+ )
183
+ ```
184
+
185
+ ### Create Collection - Advanced Configuration
186
+
187
+ ```python
188
+ from qdrant_client.models import (
189
+ Distance,
190
+ VectorParams,
191
+ OptimizersConfigDiff,
192
+ HnswConfigDiff,
193
+ QuantizationConfig,
194
+ ScalarQuantization,
195
+ ScalarType
196
+ )
197
+
198
+ client.create_collection(
199
+ collection_name="advanced_collection",
200
+ vectors_config=VectorParams(size=768, distance=Distance.COSINE),
201
+ shard_number=2,
202
+ replication_factor=1,
203
+ write_consistency_factor=1,
204
+ on_disk_payload=True,
205
+ hnsw_config=HnswConfigDiff(
206
+ m=16,
207
+ ef_construct=100,
208
+ full_scan_threshold=10000
209
+ ),
210
+ optimizers_config=OptimizersConfigDiff(
211
+ default_segment_number=2,
212
+ indexing_threshold=20000
213
+ ),
214
+ quantization_config=ScalarQuantization(
215
+ scalar=ScalarType.INT8,
216
+ quantile=0.99,
217
+ always_ram=True
218
+ )
219
+ )
220
+ ```
221
+
222
+ ### Create Collection - Sparse Vectors
223
+
224
+ ```python
225
+ from qdrant_client.models import Distance, VectorParams, SparseVectorParams
226
+
227
+ client.create_collection(
228
+ collection_name="sparse_collection",
229
+ vectors_config={
230
+ "dense": VectorParams(size=384, distance=Distance.COSINE),
231
+ "sparse": SparseVectorParams()
232
+ }
233
+ )
234
+ ```
235
+
236
+ ### Get Collection Info
237
+
238
+ ```python
239
+ info = client.get_collection("my_collection")
240
+ print(f"Points count: {info.points_count}")
241
+ print(f"Vectors config: {info.config.params.vectors}")
242
+ ```
243
+
244
+ ### Update Collection
245
+
246
+ ```python
247
+ from qdrant_client.models import OptimizersConfigDiff
248
+
249
+ client.update_collection(
250
+ collection_name="my_collection",
251
+ optimizers_config=OptimizersConfigDiff(
252
+ indexing_threshold=30000
253
+ )
254
+ )
255
+ ```
256
+
257
+ ### Delete Collection
258
+
259
+ ```python
260
+ client.delete_collection("my_collection")
261
+ ```
262
+
263
+ ## Points (Vectors)
264
+
265
+ ### Upsert Points - Basic
266
+
267
+ ```python
268
+ from qdrant_client.models import PointStruct
269
+
270
+ operation_info = client.upsert(
271
+ collection_name="my_collection",
272
+ wait=True,
273
+ points=[
274
+ PointStruct(
275
+ id=1,
276
+ vector=[0.05, 0.61, 0.76, 0.74],
277
+ payload={"city": "Berlin", "price": 1.99}
278
+ ),
279
+ PointStruct(
280
+ id=2,
281
+ vector=[0.19, 0.81, 0.75, 0.11],
282
+ payload={"city": "London", "price": 2.49}
283
+ )
284
+ ]
285
+ )
286
+ ```
287
+
288
+ ### Upsert Points - Auto ID
289
+
290
+ ```python
291
+ from qdrant_client.models import PointStruct
292
+ import uuid
293
+
294
+ points = [
295
+ PointStruct(
296
+ id=str(uuid.uuid4()),
297
+ vector=[0.1, 0.2, 0.3, 0.4],
298
+ payload={"title": "Document 1"}
299
+ )
300
+ ]
301
+
302
+ client.upsert(
303
+ collection_name="my_collection",
304
+ points=points
305
+ )
306
+ ```
307
+
308
+ ### Upsert Points - Named Vectors
309
+
310
+ ```python
311
+ from qdrant_client.models import PointStruct
312
+
313
+ client.upsert(
314
+ collection_name="multi_vector_collection",
315
+ points=[
316
+ PointStruct(
317
+ id=1,
318
+ vector={
319
+ "image": [0.1, 0.2, 0.3, 0.4],
320
+ "text": [0.5, 0.6, 0.7, 0.8]
321
+ },
322
+ payload={"title": "Product A", "category": "electronics"}
323
+ )
324
+ ]
325
+ )
326
+ ```
327
+
328
+ ### Upsert Points - Sparse Vectors
329
+
330
+ ```python
331
+ from qdrant_client.models import PointStruct, SparseVector
332
+
333
+ client.upsert(
334
+ collection_name="sparse_collection",
335
+ points=[
336
+ PointStruct(
337
+ id=1,
338
+ vector={
339
+ "dense": [0.1, 0.2, 0.3, 0.4],
340
+ "sparse": SparseVector(
341
+ indices=[1, 3, 5, 7],
342
+ values=[0.1, 0.2, 0.3, 0.4]
343
+ )
344
+ },
345
+ payload={"text": "Sample document"}
346
+ )
347
+ ]
348
+ )
349
+ ```
350
+
351
+ ### Upsert Points - Batch
352
+
353
+ ```python
354
+ from qdrant_client.models import PointStruct
355
+ import numpy as np
356
+
357
+ vectors = np.random.rand(1000, 384)
358
+ points = [
359
+ PointStruct(
360
+ id=idx,
361
+ vector=vector.tolist(),
362
+ payload={"index": idx, "category": f"cat_{idx % 10}"}
363
+ )
364
+ for idx, vector in enumerate(vectors)
365
+ ]
366
+
367
+ client.upsert(
368
+ collection_name="my_collection",
369
+ points=points,
370
+ wait=True
371
+ )
372
+ ```
373
+
374
+ ### Add Documents with FastEmbed
375
+
376
+ ```python
377
+ documents = [
378
+ "Qdrant has Langchain integrations",
379
+ "Qdrant also has Llama Index integrations",
380
+ "Qdrant is a vector database"
381
+ ]
382
+
383
+ metadata = [
384
+ {"source": "langchain-docs"},
385
+ {"source": "llamaindex-docs"},
386
+ {"source": "qdrant-docs"}
387
+ ]
388
+
389
+ ids = [1, 2, 3]
390
+
391
+ client.add(
392
+ collection_name="demo_collection",
393
+ documents=documents,
394
+ metadata=metadata,
395
+ ids=ids
396
+ )
397
+ ```
398
+
399
+ ### Retrieve Points by ID
400
+
401
+ ```python
402
+ points = client.retrieve(
403
+ collection_name="my_collection",
404
+ ids=[1, 2, 3],
405
+ with_payload=True,
406
+ with_vectors=False
407
+ )
408
+
409
+ for point in points:
410
+ print(f"ID: {point.id}, Payload: {point.payload}")
411
+ ```
412
+
413
+ ### Retrieve Points - With Vectors
414
+
415
+ ```python
416
+ points = client.retrieve(
417
+ collection_name="my_collection",
418
+ ids=[1, 2, 3],
419
+ with_payload=True,
420
+ with_vectors=True
421
+ )
422
+ ```
423
+
424
+ ### Delete Points by ID
425
+
426
+ ```python
427
+ client.delete(
428
+ collection_name="my_collection",
429
+ points_selector=[1, 2, 3]
430
+ )
431
+ ```
432
+
433
+ ### Delete Points by Filter
434
+
435
+ ```python
436
+ from qdrant_client.models import Filter, FieldCondition, MatchValue
437
+
438
+ client.delete(
439
+ collection_name="my_collection",
440
+ points_selector=Filter(
441
+ must=[
442
+ FieldCondition(
443
+ key="city",
444
+ match=MatchValue(value="Berlin")
445
+ )
446
+ ]
447
+ )
448
+ )
449
+ ```
450
+
451
+ ### Count Points
452
+
453
+ ```python
454
+ count = client.count(
455
+ collection_name="my_collection",
456
+ exact=True
457
+ )
458
+ print(f"Total points: {count.count}")
459
+ ```
460
+
461
+ ### Count Points with Filter
462
+
463
+ ```python
464
+ from qdrant_client.models import Filter, FieldCondition, Range
465
+
466
+ count = client.count(
467
+ collection_name="my_collection",
468
+ count_filter=Filter(
469
+ must=[
470
+ FieldCondition(
471
+ key="price",
472
+ range=Range(gte=2.0)
473
+ )
474
+ ]
475
+ ),
476
+ exact=True
477
+ )
478
+ ```
479
+
480
+ ## Scroll (Pagination)
481
+
482
+ ### Basic Scroll
483
+
484
+ ```python
485
+ records, next_page_offset = client.scroll(
486
+ collection_name="my_collection",
487
+ limit=10,
488
+ with_payload=True,
489
+ with_vectors=False
490
+ )
491
+
492
+ for record in records:
493
+ print(f"ID: {record.id}, Payload: {record.payload}")
494
+ ```
495
+
496
+ ### Scroll with Filter
497
+
498
+ ```python
499
+ from qdrant_client.models import Filter, FieldCondition, MatchValue
500
+
501
+ records, next_page_offset = client.scroll(
502
+ collection_name="my_collection",
503
+ scroll_filter=Filter(
504
+ must=[
505
+ FieldCondition(
506
+ key="city",
507
+ match=MatchValue(value="Berlin")
508
+ )
509
+ ]
510
+ ),
511
+ limit=20,
512
+ with_payload=True
513
+ )
514
+ ```
515
+
516
+ ### Scroll Pagination
517
+
518
+ ```python
519
+ offset = None
520
+ all_points = []
521
+
522
+ while True:
523
+ records, next_page_offset = client.scroll(
524
+ collection_name="my_collection",
525
+ limit=100,
526
+ offset=offset,
527
+ with_payload=True,
528
+ with_vectors=False
529
+ )
530
+
531
+ all_points.extend(records)
532
+
533
+ if next_page_offset is None:
534
+ break
535
+
536
+ offset = next_page_offset
537
+
538
+ print(f"Total points retrieved: {len(all_points)}")
539
+ ```
540
+
541
+ ### Scroll with Order By
542
+
543
+ ```python
544
+ records, next_page_offset = client.scroll(
545
+ collection_name="my_collection",
546
+ limit=15,
547
+ order_by="timestamp",
548
+ with_payload=True
549
+ )
550
+ ```
551
+
552
+ ## Search
553
+
554
+ ### Basic Vector Search
555
+
556
+ ```python
557
+ search_result = client.search(
558
+ collection_name="my_collection",
559
+ query_vector=[0.18, 0.81, 0.75, 0.12],
560
+ limit=5
561
+ )
562
+
563
+ for result in search_result:
564
+ print(f"ID: {result.id}, Score: {result.score}")
565
+ print(f"Payload: {result.payload}")
566
+ ```
567
+
568
+ ### Search with Score Threshold
569
+
570
+ ```python
571
+ search_result = client.search(
572
+ collection_name="my_collection",
573
+ query_vector=[0.18, 0.81, 0.75, 0.12],
574
+ limit=10,
575
+ score_threshold=0.8
576
+ )
577
+ ```
578
+
579
+ ### Search Named Vectors
580
+
581
+ ```python
582
+ search_result = client.search(
583
+ collection_name="multi_vector_collection",
584
+ query_vector=[0.1, 0.2, 0.3, 0.4],
585
+ using="text",
586
+ limit=5
587
+ )
588
+ ```
589
+
590
+ ### Search without Vectors
591
+
592
+ ```python
593
+ search_result = client.search(
594
+ collection_name="my_collection",
595
+ query_vector=[0.18, 0.81, 0.75, 0.12],
596
+ limit=5,
597
+ with_payload=True,
598
+ with_vectors=False
599
+ )
600
+ ```
601
+
602
+ ### Text Query with FastEmbed
603
+
604
+ ```python
605
+ search_result = client.query(
606
+ collection_name="demo_collection",
607
+ query_text="This is a query document",
608
+ limit=5
609
+ )
610
+
611
+ for result in search_result:
612
+ print(f"Score: {result.score}, Text: {result.payload}")
613
+ ```
614
+
615
+ ## Filtering
616
+
617
+ ### Match Filter
618
+
619
+ ```python
620
+ from qdrant_client.models import Filter, FieldCondition, MatchValue
621
+
622
+ search_result = client.search(
623
+ collection_name="my_collection",
624
+ query_vector=[0.2, 0.1, 0.9, 0.7],
625
+ query_filter=Filter(
626
+ must=[
627
+ FieldCondition(
628
+ key="city",
629
+ match=MatchValue(value="London")
630
+ )
631
+ ]
632
+ ),
633
+ limit=5
634
+ )
635
+ ```
636
+
637
+ ### Range Filter
638
+
639
+ ```python
640
+ from qdrant_client.models import Filter, FieldCondition, Range
641
+
642
+ search_result = client.search(
643
+ collection_name="my_collection",
644
+ query_vector=[0.2, 0.1, 0.9, 0.7],
645
+ query_filter=Filter(
646
+ must=[
647
+ FieldCondition(
648
+ key="price",
649
+ range=Range(gte=1.0, lt=3.0)
650
+ )
651
+ ]
652
+ ),
653
+ limit=5
654
+ )
655
+ ```
656
+
657
+ ### Multiple Conditions (AND)
658
+
659
+ ```python
660
+ from qdrant_client.models import Filter, FieldCondition, MatchValue, Range
661
+
662
+ search_result = client.search(
663
+ collection_name="my_collection",
664
+ query_vector=[0.2, 0.1, 0.9, 0.7],
665
+ query_filter=Filter(
666
+ must=[
667
+ FieldCondition(
668
+ key="city",
669
+ match=MatchValue(value="Berlin")
670
+ ),
671
+ FieldCondition(
672
+ key="price",
673
+ range=Range(gte=2.0)
674
+ )
675
+ ]
676
+ ),
677
+ limit=5
678
+ )
679
+ ```
680
+
681
+ ### OR Conditions
682
+
683
+ ```python
684
+ from qdrant_client.models import Filter, FieldCondition, MatchValue
685
+
686
+ search_result = client.search(
687
+ collection_name="my_collection",
688
+ query_vector=[0.2, 0.1, 0.9, 0.7],
689
+ query_filter=Filter(
690
+ should=[
691
+ FieldCondition(
692
+ key="city",
693
+ match=MatchValue(value="Berlin")
694
+ ),
695
+ FieldCondition(
696
+ key="city",
697
+ match=MatchValue(value="London")
698
+ )
699
+ ]
700
+ ),
701
+ limit=5
702
+ )
703
+ ```
704
+
705
+ ### NOT Conditions
706
+
707
+ ```python
708
+ from qdrant_client.models import Filter, FieldCondition, MatchValue
709
+
710
+ search_result = client.search(
711
+ collection_name="my_collection",
712
+ query_vector=[0.2, 0.1, 0.9, 0.7],
713
+ query_filter=Filter(
714
+ must_not=[
715
+ FieldCondition(
716
+ key="city",
717
+ match=MatchValue(value="Berlin")
718
+ )
719
+ ]
720
+ ),
721
+ limit=5
722
+ )
723
+ ```
724
+
725
+ ### Complex Filter
726
+
727
+ ```python
728
+ from qdrant_client.models import Filter, FieldCondition, MatchValue, Range
729
+
730
+ search_result = client.search(
731
+ collection_name="my_collection",
732
+ query_vector=[0.2, 0.1, 0.9, 0.7],
733
+ query_filter=Filter(
734
+ must=[
735
+ FieldCondition(
736
+ key="category",
737
+ match=MatchValue(value="electronics")
738
+ )
739
+ ],
740
+ should=[
741
+ FieldCondition(
742
+ key="price",
743
+ range=Range(lt=100)
744
+ ),
745
+ FieldCondition(
746
+ key="discount",
747
+ match=MatchValue(value=True)
748
+ )
749
+ ],
750
+ must_not=[
751
+ FieldCondition(
752
+ key="out_of_stock",
753
+ match=MatchValue(value=True)
754
+ )
755
+ ]
756
+ ),
757
+ limit=10
758
+ )
759
+ ```
760
+
761
+ ### Match Any (Array)
762
+
763
+ ```python
764
+ from qdrant_client.models import Filter, FieldCondition, MatchAny
765
+
766
+ search_result = client.search(
767
+ collection_name="my_collection",
768
+ query_vector=[0.2, 0.1, 0.9, 0.7],
769
+ query_filter=Filter(
770
+ must=[
771
+ FieldCondition(
772
+ key="tags",
773
+ match=MatchAny(any=["electronics", "gadgets", "tech"])
774
+ )
775
+ ]
776
+ ),
777
+ limit=5
778
+ )
779
+ ```
780
+
781
+ ### Geo Radius Filter
782
+
783
+ ```python
784
+ from qdrant_client.models import Filter, FieldCondition, GeoRadius, GeoPoint
785
+
786
+ search_result = client.search(
787
+ collection_name="my_collection",
788
+ query_vector=[0.2, 0.1, 0.9, 0.7],
789
+ query_filter=Filter(
790
+ must=[
791
+ FieldCondition(
792
+ key="location",
793
+ geo_radius=GeoRadius(
794
+ center=GeoPoint(lon=13.404954, lat=52.520008),
795
+ radius=5000.0
796
+ )
797
+ )
798
+ ]
799
+ ),
800
+ limit=5
801
+ )
802
+ ```
803
+
804
+ ### Is Empty Filter
805
+
806
+ ```python
807
+ from qdrant_client.models import Filter, IsEmptyCondition
808
+
809
+ search_result = client.search(
810
+ collection_name="my_collection",
811
+ query_vector=[0.2, 0.1, 0.9, 0.7],
812
+ query_filter=Filter(
813
+ must=[
814
+ IsEmptyCondition(is_empty={"key": "tags"})
815
+ ]
816
+ ),
817
+ limit=5
818
+ )
819
+ ```
820
+
821
+ ### Is Null Filter
822
+
823
+ ```python
824
+ from qdrant_client.models import Filter, IsNullCondition
825
+
826
+ search_result = client.search(
827
+ collection_name="my_collection",
828
+ query_vector=[0.2, 0.1, 0.9, 0.7],
829
+ query_filter=Filter(
830
+ must=[
831
+ IsNullCondition(is_null={"key": "description"})
832
+ ]
833
+ ),
834
+ limit=5
835
+ )
836
+ ```
837
+
838
+ ## Recommend
839
+
840
+ ### Basic Recommend
841
+
842
+ ```python
843
+ recommend_result = client.recommend(
844
+ collection_name="my_collection",
845
+ positive=[1, 2, 3],
846
+ negative=[10],
847
+ limit=5
848
+ )
849
+
850
+ for result in recommend_result:
851
+ print(f"ID: {result.id}, Score: {result.score}")
852
+ ```
853
+
854
+ ### Recommend with Vectors
855
+
856
+ ```python
857
+ recommend_result = client.recommend(
858
+ collection_name="my_collection",
859
+ positive=[1, 2, [0.1, 0.2, 0.3, 0.4]],
860
+ negative=[[0.9, 0.8, 0.7, 0.6]],
861
+ limit=5
862
+ )
863
+ ```
864
+
865
+ ### Recommend with Filter
866
+
867
+ ```python
868
+ from qdrant_client.models import Filter, FieldCondition, MatchValue
869
+
870
+ recommend_result = client.recommend(
871
+ collection_name="my_collection",
872
+ positive=[1, 2, 3],
873
+ negative=[10],
874
+ query_filter=Filter(
875
+ must=[
876
+ FieldCondition(
877
+ key="category",
878
+ match=MatchValue(value="electronics")
879
+ )
880
+ ]
881
+ ),
882
+ limit=5
883
+ )
884
+ ```
885
+
886
+ ### Recommend Strategy
887
+
888
+ ```python
889
+ from qdrant_client.models import RecommendStrategy
890
+
891
+ recommend_result = client.recommend(
892
+ collection_name="my_collection",
893
+ positive=[1, 2, 3],
894
+ negative=[10],
895
+ strategy=RecommendStrategy.AVERAGE_VECTOR,
896
+ limit=5
897
+ )
898
+ ```
899
+
900
+ ### Recommend Named Vectors
901
+
902
+ ```python
903
+ recommend_result = client.recommend(
904
+ collection_name="multi_vector_collection",
905
+ positive=[1, 2],
906
+ negative=[10],
907
+ using="text",
908
+ limit=5
909
+ )
910
+ ```
911
+
912
+ ## Discover
913
+
914
+ ### Basic Discover
915
+
916
+ ```python
917
+ from qdrant_client.models import ContextPair
918
+
919
+ discover_result = client.discover(
920
+ collection_name="my_collection",
921
+ target=100,
922
+ context=[
923
+ ContextPair(positive=200, negative=300),
924
+ ContextPair(positive=150, negative=250)
925
+ ],
926
+ limit=10
927
+ )
928
+ ```
929
+
930
+ ### Discover with Filter
931
+
932
+ ```python
933
+ from qdrant_client.models import ContextPair, Filter, FieldCondition, MatchValue
934
+
935
+ discover_result = client.discover(
936
+ collection_name="my_collection",
937
+ target=100,
938
+ context=[
939
+ ContextPair(positive=200, negative=300)
940
+ ],
941
+ query_filter=Filter(
942
+ must=[
943
+ FieldCondition(
944
+ key="active",
945
+ match=MatchValue(value=True)
946
+ )
947
+ ]
948
+ ),
949
+ limit=10
950
+ )
951
+ ```
952
+
953
+ ## Query API (Universal)
954
+
955
+ ### Vector Query
956
+
957
+ ```python
958
+ from qdrant_client.models import QueryRequest, VectorQuery
959
+
960
+ query_result = client.query_points(
961
+ collection_name="my_collection",
962
+ query=[0.1, 0.2, 0.3, 0.4],
963
+ limit=10
964
+ )
965
+ ```
966
+
967
+ ### Recommend Query
968
+
969
+ ```python
970
+ from qdrant_client.models import RecommendQuery
971
+
972
+ query_result = client.query_points(
973
+ collection_name="my_collection",
974
+ query=RecommendQuery(
975
+ recommend=RecommendInput(
976
+ positive=[100, 231],
977
+ negative=[718]
978
+ )
979
+ ),
980
+ limit=10
981
+ )
982
+ ```
983
+
984
+ ### Discover Query
985
+
986
+ ```python
987
+ from qdrant_client.models import DiscoverQuery, ContextPair
988
+
989
+ query_result = client.query_points(
990
+ collection_name="my_collection",
991
+ query=DiscoverQuery(
992
+ discover=DiscoverInput(
993
+ target=100,
994
+ context=[
995
+ ContextPair(positive=200, negative=300)
996
+ ]
997
+ )
998
+ ),
999
+ limit=10
1000
+ )
1001
+ ```
1002
+
1003
+ ### Context Query
1004
+
1005
+ ```python
1006
+ from qdrant_client.models import ContextQuery, ContextPair
1007
+
1008
+ query_result = client.query_points(
1009
+ collection_name="my_collection",
1010
+ query=ContextQuery(
1011
+ context=[
1012
+ ContextPair(positive=100, negative=718),
1013
+ ContextPair(positive=200, negative=300)
1014
+ ]
1015
+ ),
1016
+ limit=10
1017
+ )
1018
+ ```
1019
+
1020
+ ## Batch Operations
1021
+
1022
+ ### Batch Search
1023
+
1024
+ ```python
1025
+ from qdrant_client.models import SearchRequest, Filter, FieldCondition, MatchValue
1026
+
1027
+ requests = [
1028
+ SearchRequest(
1029
+ vector=[0.1, 0.2, 0.3, 0.4],
1030
+ limit=5,
1031
+ filter=Filter(
1032
+ must=[
1033
+ FieldCondition(
1034
+ key="category",
1035
+ match=MatchValue(value="electronics")
1036
+ )
1037
+ ]
1038
+ )
1039
+ ),
1040
+ SearchRequest(
1041
+ vector=[0.5, 0.6, 0.7, 0.8],
1042
+ limit=5,
1043
+ filter=Filter(
1044
+ must=[
1045
+ FieldCondition(
1046
+ key="category",
1047
+ match=MatchValue(value="books")
1048
+ )
1049
+ ]
1050
+ )
1051
+ )
1052
+ ]
1053
+
1054
+ results = client.search_batch(
1055
+ collection_name="my_collection",
1056
+ requests=requests
1057
+ )
1058
+
1059
+ for i, result in enumerate(results):
1060
+ print(f"Results for request {i}:")
1061
+ for point in result:
1062
+ print(f" ID: {point.id}, Score: {point.score}")
1063
+ ```
1064
+
1065
+ ### Batch Query
1066
+
1067
+ ```python
1068
+ from qdrant_client.models import QueryRequest
1069
+
1070
+ requests = [
1071
+ QueryRequest(
1072
+ query=[0.1, 0.2, 0.3, 0.4],
1073
+ limit=5
1074
+ ),
1075
+ QueryRequest(
1076
+ query=[0.5, 0.6, 0.7, 0.8],
1077
+ limit=5
1078
+ )
1079
+ ]
1080
+
1081
+ results = client.query_batch_points(
1082
+ collection_name="my_collection",
1083
+ requests=requests
1084
+ )
1085
+ ```
1086
+
1087
+ ### Batch Recommend
1088
+
1089
+ ```python
1090
+ from qdrant_client.models import RecommendRequest, Filter, FieldCondition, MatchValue
1091
+
1092
+ requests = [
1093
+ RecommendRequest(
1094
+ positive=[100, 231],
1095
+ negative=[718],
1096
+ limit=10
1097
+ ),
1098
+ RecommendRequest(
1099
+ positive=[500, 600],
1100
+ negative=[700, 800],
1101
+ limit=10,
1102
+ filter=Filter(
1103
+ must=[
1104
+ FieldCondition(
1105
+ key="active",
1106
+ match=MatchValue(value=True)
1107
+ )
1108
+ ]
1109
+ )
1110
+ )
1111
+ ]
1112
+
1113
+ results = client.recommend_batch(
1114
+ collection_name="my_collection",
1115
+ requests=requests
1116
+ )
1117
+ ```
1118
+
1119
+ ### Batch Update Points
1120
+
1121
+ ```python
1122
+ from qdrant_client.models import (
1123
+ PointStruct,
1124
+ UpsertOperation,
1125
+ DeleteOperation,
1126
+ SetPayloadOperation,
1127
+ PointIdsList,
1128
+ UpdateStatus
1129
+ )
1130
+
1131
+ client.batch_update_points(
1132
+ collection_name="my_collection",
1133
+ update_operations=[
1134
+ UpsertOperation(
1135
+ upsert=PointsList(
1136
+ points=[
1137
+ PointStruct(
1138
+ id=1,
1139
+ vector=[1.0, 2.0, 3.0, 4.0],
1140
+ payload={"title": "Item 1"}
1141
+ )
1142
+ ]
1143
+ )
1144
+ ),
1145
+ DeleteOperation(
1146
+ delete=PointIdsList(points=[5, 6, 7])
1147
+ ),
1148
+ SetPayloadOperation(
1149
+ set_payload=SetPayload(
1150
+ payload={"updated": True},
1151
+ points=[1, 2, 3]
1152
+ )
1153
+ )
1154
+ ]
1155
+ )
1156
+ ```
1157
+
1158
+ ### Mixed Batch Operations
1159
+
1160
+ ```python
1161
+ from qdrant_client.models import (
1162
+ UpsertOperation,
1163
+ UpdateVectorsOperation,
1164
+ DeletePayloadOperation,
1165
+ PointStruct,
1166
+ PointsList,
1167
+ UpdateVectors,
1168
+ PointVectors,
1169
+ DeletePayload,
1170
+ PointIdsList
1171
+ )
1172
+
1173
+ client.batch_update_points(
1174
+ collection_name="my_collection",
1175
+ update_operations=[
1176
+ UpsertOperation(
1177
+ upsert=PointsList(
1178
+ points=[
1179
+ PointStruct(
1180
+ id=1,
1181
+ vector=[1.0, 2.0, 3.0, 4.0],
1182
+ payload={}
1183
+ )
1184
+ ]
1185
+ )
1186
+ ),
1187
+ UpdateVectorsOperation(
1188
+ update_vectors=UpdateVectors(
1189
+ points=[
1190
+ PointVectors(
1191
+ id=2,
1192
+ vector=[5.0, 6.0, 7.0, 8.0]
1193
+ )
1194
+ ]
1195
+ )
1196
+ ),
1197
+ DeletePayloadOperation(
1198
+ delete_payload=DeletePayload(
1199
+ keys=["old_field"],
1200
+ points=PointIdsList(points=[3, 4])
1201
+ )
1202
+ )
1203
+ ]
1204
+ )
1205
+ ```
1206
+
1207
+ ## Payload Operations
1208
+
1209
+ ### Set Payload
1210
+
1211
+ ```python
1212
+ from datetime import datetime
1213
+
1214
+ client.set_payload(
1215
+ collection_name="my_collection",
1216
+ payload={
1217
+ "updated_at": datetime.now().isoformat(),
1218
+ "verified": True
1219
+ },
1220
+ points=[1, 2, 3]
1221
+ )
1222
+ ```
1223
+
1224
+ ### Set Payload with Filter
1225
+
1226
+ ```python
1227
+ from qdrant_client.models import Filter, FieldCondition, Range
1228
+
1229
+ client.set_payload(
1230
+ collection_name="my_collection",
1231
+ payload={"promoted": True},
1232
+ points=Filter(
1233
+ must=[
1234
+ FieldCondition(
1235
+ key="price",
1236
+ range=Range(lt=50)
1237
+ )
1238
+ ]
1239
+ )
1240
+ )
1241
+ ```
1242
+
1243
+ ### Overwrite Payload
1244
+
1245
+ ```python
1246
+ client.overwrite_payload(
1247
+ collection_name="my_collection",
1248
+ payload={
1249
+ "title": "New Title",
1250
+ "price": 99.99
1251
+ },
1252
+ points=[1, 2]
1253
+ )
1254
+ ```
1255
+
1256
+ ### Delete Payload Keys
1257
+
1258
+ ```python
1259
+ client.delete_payload(
1260
+ collection_name="my_collection",
1261
+ keys=["old_field", "deprecated_field"],
1262
+ points=[1, 2, 3]
1263
+ )
1264
+ ```
1265
+
1266
+ ### Clear Payload
1267
+
1268
+ ```python
1269
+ client.clear_payload(
1270
+ collection_name="my_collection",
1271
+ points_selector=[1, 2, 3]
1272
+ )
1273
+ ```
1274
+
1275
+ ## Payload Indexing
1276
+
1277
+ ### Create Payload Index - Keyword
1278
+
1279
+ ```python
1280
+ client.create_payload_index(
1281
+ collection_name="my_collection",
1282
+ field_name="city",
1283
+ field_schema="keyword"
1284
+ )
1285
+ ```
1286
+
1287
+ ### Create Payload Index - Integer
1288
+
1289
+ ```python
1290
+ client.create_payload_index(
1291
+ collection_name="my_collection",
1292
+ field_name="price",
1293
+ field_schema="integer"
1294
+ )
1295
+ ```
1296
+
1297
+ ### Create Payload Index - Float
1298
+
1299
+ ```python
1300
+ client.create_payload_index(
1301
+ collection_name="my_collection",
1302
+ field_name="rating",
1303
+ field_schema="float"
1304
+ )
1305
+ ```
1306
+
1307
+ ### Create Payload Index - Geo
1308
+
1309
+ ```python
1310
+ client.create_payload_index(
1311
+ collection_name="my_collection",
1312
+ field_name="location",
1313
+ field_schema="geo"
1314
+ )
1315
+ ```
1316
+
1317
+ ### Create Payload Index - Text
1318
+
1319
+ ```python
1320
+ from qdrant_client.models import TextIndexParams, TokenizerType
1321
+
1322
+ client.create_payload_index(
1323
+ collection_name="my_collection",
1324
+ field_name="description",
1325
+ field_schema=TextIndexParams(
1326
+ type="text",
1327
+ tokenizer=TokenizerType.WORD,
1328
+ min_token_len=2,
1329
+ max_token_len=20,
1330
+ lowercase=True
1331
+ )
1332
+ )
1333
+ ```
1334
+
1335
+ ### Delete Payload Index
1336
+
1337
+ ```python
1338
+ client.delete_payload_index(
1339
+ collection_name="my_collection",
1340
+ field_name="old_index_field"
1341
+ )
1342
+ ```
1343
+
1344
+ ## Snapshots
1345
+
1346
+ ### Create Collection Snapshot
1347
+
1348
+ ```python
1349
+ snapshot_info = client.create_snapshot(
1350
+ collection_name="my_collection"
1351
+ )
1352
+ print(f"Snapshot created: {snapshot_info.name}")
1353
+ ```
1354
+
1355
+ ### List Collection Snapshots
1356
+
1357
+ ```python
1358
+ snapshots = client.list_snapshots(
1359
+ collection_name="my_collection"
1360
+ )
1361
+
1362
+ for snapshot in snapshots:
1363
+ print(f"Snapshot: {snapshot.name}, Size: {snapshot.size}")
1364
+ ```
1365
+
1366
+ ### Delete Collection Snapshot
1367
+
1368
+ ```python
1369
+ client.delete_snapshot(
1370
+ collection_name="my_collection",
1371
+ snapshot_name="snapshot_2025-01-15-10-30-00"
1372
+ )
1373
+ ```
1374
+
1375
+ ### Create Full Storage Snapshot
1376
+
1377
+ ```python
1378
+ snapshot_info = client.create_full_snapshot()
1379
+ print(f"Full snapshot created: {snapshot_info.name}")
1380
+ ```
1381
+
1382
+ ### List Full Snapshots
1383
+
1384
+ ```python
1385
+ snapshots = client.list_full_snapshots()
1386
+ for snapshot in snapshots:
1387
+ print(f"Full snapshot: {snapshot.name}")
1388
+ ```
1389
+
1390
+ ### Download Snapshot
1391
+
1392
+ ```python
1393
+ client.download_snapshot(
1394
+ collection_name="my_collection",
1395
+ snapshot_name="snapshot_2025-01-15-10-30-00",
1396
+ snapshot_path="./backups/snapshot.snapshot"
1397
+ )
1398
+ ```
1399
+
1400
+ ## Cluster Operations
1401
+
1402
+ ### Get Cluster Info
1403
+
1404
+ ```python
1405
+ cluster_info = client.cluster_status()
1406
+ print(f"Peers: {cluster_info.peers}")
1407
+ print(f"Raft info: {cluster_info.raft_info}")
1408
+ ```
1409
+
1410
+ ## Async Operations
1411
+
1412
+ ### Async Client Usage
1413
+
1414
+ ```python
1415
+ from qdrant_client import AsyncQdrantClient
1416
+ from qdrant_client.models import Distance, VectorParams, PointStruct
1417
+ import asyncio
1418
+
1419
+ async def main():
1420
+ client = AsyncQdrantClient(url="http://localhost:6333")
1421
+
1422
+ # Create collection
1423
+ await client.create_collection(
1424
+ collection_name="async_collection",
1425
+ vectors_config=VectorParams(size=4, distance=Distance.COSINE)
1426
+ )
1427
+
1428
+ # Upsert points
1429
+ await client.upsert(
1430
+ collection_name="async_collection",
1431
+ points=[
1432
+ PointStruct(
1433
+ id=1,
1434
+ vector=[0.1, 0.2, 0.3, 0.4],
1435
+ payload={"title": "Async document"}
1436
+ )
1437
+ ]
1438
+ )
1439
+
1440
+ # Search
1441
+ results = await client.search(
1442
+ collection_name="async_collection",
1443
+ query_vector=[0.1, 0.2, 0.3, 0.4],
1444
+ limit=5
1445
+ )
1446
+
1447
+ for result in results:
1448
+ print(f"ID: {result.id}, Score: {result.score}")
1449
+
1450
+ await client.close()
1451
+
1452
+ asyncio.run(main())
1453
+ ```
1454
+
1455
+ ### Async Context Manager
1456
+
1457
+ ```python
1458
+ from qdrant_client import AsyncQdrantClient
1459
+
1460
+ async def main():
1461
+ async with AsyncQdrantClient(url="http://localhost:6333") as client:
1462
+ collections = await client.get_collections()
1463
+ print(collections)
1464
+
1465
+ asyncio.run(main())
1466
+ ```
1467
+
1468
+ ## Error Handling
1469
+
1470
+ ### Basic Error Handling
1471
+
1472
+ ```python
1473
+ try:
1474
+ search_result = client.search(
1475
+ collection_name="my_collection",
1476
+ query_vector=[0.1, 0.2, 0.3, 0.4],
1477
+ limit=10
1478
+ )
1479
+ except Exception as e:
1480
+ print(f"Search failed: {e}")
1481
+ ```
1482
+
1483
+ ### Check Collection Exists Before Operations
1484
+
1485
+ ```python
1486
+ if not client.collection_exists("my_collection"):
1487
+ from qdrant_client.models import Distance, VectorParams
1488
+
1489
+ client.create_collection(
1490
+ collection_name="my_collection",
1491
+ vectors_config=VectorParams(size=384, distance=Distance.COSINE)
1492
+ )
1493
+ ```
1494
+
1495
+ ### Retry Logic
1496
+
1497
+ ```python
1498
+ import time
1499
+ from qdrant_client.http.exceptions import UnexpectedResponse
1500
+
1501
+ def search_with_retry(client, collection_name, query_vector, max_retries=3):
1502
+ for attempt in range(max_retries):
1503
+ try:
1504
+ return client.search(
1505
+ collection_name=collection_name,
1506
+ query_vector=query_vector,
1507
+ limit=5
1508
+ )
1509
+ except UnexpectedResponse as e:
1510
+ if attempt == max_retries - 1:
1511
+ raise
1512
+ time.sleep(2 ** attempt)
1513
+
1514
+ results = search_with_retry(client, "my_collection", [0.1, 0.2, 0.3, 0.4])
1515
+ ```
1516
+
1517
+ ## Complete Example
1518
+
1519
+ ```python
1520
+ from qdrant_client import QdrantClient
1521
+ from qdrant_client.models import Distance, VectorParams, PointStruct, Filter, FieldCondition, MatchValue, Range
1522
+ import numpy as np
1523
+
1524
+ # Initialize client
1525
+ client = QdrantClient(url="http://localhost:6333")
1526
+
1527
+ collection_name = "products"
1528
+
1529
+ # Create collection
1530
+ if not client.collection_exists(collection_name):
1531
+ client.create_collection(
1532
+ collection_name=collection_name,
1533
+ vectors_config=VectorParams(size=4, distance=Distance.COSINE)
1534
+ )
1535
+
1536
+ # Upsert points
1537
+ client.upsert(
1538
+ collection_name=collection_name,
1539
+ points=[
1540
+ PointStruct(
1541
+ id=1,
1542
+ vector=[0.05, 0.61, 0.76, 0.74],
1543
+ payload={
1544
+ "name": "Product A",
1545
+ "category": "electronics",
1546
+ "price": 299.99,
1547
+ "in_stock": True
1548
+ }
1549
+ ),
1550
+ PointStruct(
1551
+ id=2,
1552
+ vector=[0.19, 0.81, 0.75, 0.11],
1553
+ payload={
1554
+ "name": "Product B",
1555
+ "category": "electronics",
1556
+ "price": 199.99,
1557
+ "in_stock": True
1558
+ }
1559
+ ),
1560
+ PointStruct(
1561
+ id=3,
1562
+ vector=[0.36, 0.55, 0.47, 0.94],
1563
+ payload={
1564
+ "name": "Product C",
1565
+ "category": "books",
1566
+ "price": 29.99,
1567
+ "in_stock": False
1568
+ }
1569
+ ),
1570
+ PointStruct(
1571
+ id=4,
1572
+ vector=[0.88, 0.22, 0.33, 0.44],
1573
+ payload={
1574
+ "name": "Product D",
1575
+ "category": "electronics",
1576
+ "price": 399.99,
1577
+ "in_stock": True
1578
+ }
1579
+ )
1580
+ ],
1581
+ wait=True
1582
+ )
1583
+
1584
+ # Basic search
1585
+ print("=== Basic Search ===")
1586
+ results = client.search(
1587
+ collection_name=collection_name,
1588
+ query_vector=[0.2, 0.7, 0.8, 0.1],
1589
+ limit=3
1590
+ )
1591
+
1592
+ for result in results:
1593
+ print(f"{result.payload['name']} - Score: {result.score:.4f}")
1594
+
1595
+ # Filtered search
1596
+ print("\n=== Filtered Search (electronics under $300) ===")
1597
+ filtered_results = client.search(
1598
+ collection_name=collection_name,
1599
+ query_vector=[0.2, 0.7, 0.8, 0.1],
1600
+ query_filter=Filter(
1601
+ must=[
1602
+ FieldCondition(
1603
+ key="category",
1604
+ match=MatchValue(value="electronics")
1605
+ ),
1606
+ FieldCondition(
1607
+ key="price",
1608
+ range=Range(lt=300)
1609
+ ),
1610
+ FieldCondition(
1611
+ key="in_stock",
1612
+ match=MatchValue(value=True)
1613
+ )
1614
+ ]
1615
+ ),
1616
+ limit=5
1617
+ )
1618
+
1619
+ for result in filtered_results:
1620
+ print(f"{result.payload['name']} - ${result.payload['price']}")
1621
+
1622
+ # Count points
1623
+ count = client.count(collection_name=collection_name, exact=True)
1624
+ print(f"\n=== Total Points: {count.count} ===")
1625
+
1626
+ # Recommend
1627
+ print("\n=== Recommendations based on Product A ===")
1628
+ recommendations = client.recommend(
1629
+ collection_name=collection_name,
1630
+ positive=[1],
1631
+ negative=[],
1632
+ limit=3
1633
+ )
1634
+
1635
+ for rec in recommendations:
1636
+ print(f"{rec.payload['name']} - Score: {rec.score:.4f}")
1637
+
1638
+ # Scroll through all points
1639
+ print("\n=== All Products (via scroll) ===")
1640
+ records, next_offset = client.scroll(
1641
+ collection_name=collection_name,
1642
+ limit=10,
1643
+ with_payload=True,
1644
+ with_vectors=False
1645
+ )
1646
+
1647
+ for record in records:
1648
+ print(f"ID {record.id}: {record.payload['name']} - {record.payload['category']}")
1649
+
1650
+ # Cleanup
1651
+ client.delete_collection(collection_name)
1652
+ print(f"\n=== Collection '{collection_name}' deleted ===")
1653
+ ```