feat: Improve Qdrant client example

- Simplify Qdrant client example script, removing unnecessary
  boilerplate and improving readability.
- Add functions for creating, getting, deleting and listing
  collections.
- Add function to check collection existence.
- Improve error handling and logging.
This commit is contained in:
Mahmoud Emad
2025-03-13 16:06:23 +02:00
parent f9ea731a6e
commit e374520654
6 changed files with 568 additions and 999 deletions

217
examples/clients/qdrant_example.vsh Normal file → Executable file
View File

@@ -1,209 +1,46 @@
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib.clients.qdrant
import os
import flag
import freeflowuniverse.herolib.core.httpconnection
import rand
mut fp := flag.new_flag_parser(os.args)
fp.application('qdrant_example.vsh')
fp.version('v0.1.0')
fp.description('Example script demonstrating Qdrant client usage')
fp.skip_executable()
// 1. Get the qdrant client
mut qdrant_client := qdrant.get()!
help_requested := fp.bool('help', `h`, false, 'Show help message')
// 2. Generate collection name
if help_requested {
println(fp.usage())
exit(0)
}
collection_name := 'collection_' + rand.string(4)
additional_args := fp.finalize() or {
eprintln(err)
println(fp.usage())
exit(1)
}
// 2. Create a new collection
// Initialize Qdrant client
mut client := qdrant.get(name: 'default') or {
// If client doesn't exist, create a new one
mut new_client := qdrant.QdrantClient{
name: 'default'
url: 'http://localhost:6333'
}
qdrant.set(new_client) or {
eprintln('Failed to set Qdrant client: ${err}')
exit(1)
}
new_client
}
println('Connected to Qdrant at ${client.url}')
// Check if Qdrant is healthy
is_healthy := client.health_check() or {
eprintln('Failed to check Qdrant health: ${err}')
exit(1)
}
if !is_healthy {
eprintln('Qdrant is not healthy')
exit(1)
}
println('Qdrant is healthy')
// Get service info
service_info := client.get_service_info() or {
eprintln('Failed to get service info: ${err}')
exit(1)
}
println('Qdrant version: ${service_info.version}')
// Collection name for our example
collection_name := 'example_collection'
// Check if collection exists and delete it if it does
collections := client.list_collections() or {
eprintln('Failed to list collections: ${err}')
exit(1)
}
if collection_name in collections.result {
println('Collection ${collection_name} already exists, deleting it...')
client.delete_collection(collection_name: collection_name) or {
eprintln('Failed to delete collection: ${err}')
exit(1)
}
println('Collection deleted')
}
// Create a new collection
println('Creating collection ${collection_name}...')
vectors_config := qdrant.VectorsConfig{
size: 4 // Small size for example purposes
distance: .cosine
}
client.create_collection(
created_collection := qdrant_client.create_collection(
collection_name: collection_name
vectors: vectors_config
) or {
eprintln('Failed to create collection: ${err}')
exit(1)
}
size: 15
distance: 'Cosine'
)!
println('Collection created')
println('Created Collection: ${created_collection}')
// Upsert some points
println('Upserting points...')
points := [
qdrant.PointStruct{
id: '1'
vector: [f32(0.1), 0.2, 0.3, 0.4]
payload: {
'color': 'red'
'category': 'furniture'
'name': 'chair'
}
},
qdrant.PointStruct{
id: '2'
vector: [f32(0.2), 0.3, 0.4, 0.5]
payload: {
'color': 'blue'
'category': 'electronics'
'name': 'laptop'
}
},
qdrant.PointStruct{
id: '3'
vector: [f32(0.3), 0.4, 0.5, 0.6]
payload: {
'color': 'green'
'category': 'food'
'name': 'apple'
}
}
]
client.upsert_points(
// 3. Get the created collection
get_collection := qdrant_client.get_collection(
collection_name: collection_name
points: points
wait: true
) or {
eprintln('Failed to upsert points: ${err}')
exit(1)
}
)!
println('Points upserted')
println('Get Collection: ${get_collection}')
// Get collection info to verify points were added
collection_info := client.get_collection(collection_name: collection_name) or {
eprintln('Failed to get collection info: ${err}')
exit(1)
}
println('Collection has ${collection_info.vectors_count} points')
// Search for points
println('Searching for points similar to [0.1, 0.2, 0.3, 0.4]...')
search_result := client.search(
// 4. Delete the created collection
deleted_collection := qdrant_client.delete_collection(
collection_name: collection_name
vector: [f32(0.1), 0.2, 0.3, 0.4]
limit: 3
) or {
eprintln('Failed to search points: ${err}')
exit(1)
}
)!
println('Search results:')
for i, point in search_result.result {
println(' ${i+1}. ID: ${point.id}, Score: ${point.score}')
if payload := point.payload {
println(' Name: ${payload['name']}')
println(' Category: ${payload['category']}')
println(' Color: ${payload['color']}')
}
}
println('Deleted Collection: ${deleted_collection}')
// Search with filter
println('\nSearching for points with category "electronics"...')
filter := qdrant.Filter{
must: [
qdrant.FieldCondition{
key: 'category'
match: 'electronics'
}
]
}
// 5. List all collections
list_collection := qdrant_client.list_collections()!
println('List Collection: ${list_collection}')
filtered_search := client.search(
// 6. Check collection existence
collection_existence := qdrant_client.is_exists(
collection_name: collection_name
vector: [f32(0.1), 0.2, 0.3, 0.4]
filter: filter
limit: 3
) or {
eprintln('Failed to search with filter: ${err}')
exit(1)
}
println('Filtered search results:')
for i, point in filtered_search.result {
println(' ${i+1}. ID: ${point.id}, Score: ${point.score}')
if payload := point.payload {
println(' Name: ${payload['name']}')
println(' Category: ${payload['category']}')
println(' Color: ${payload['color']}')
}
}
// Clean up - delete the collection
println('\nCleaning up - deleting collection...')
client.delete_collection(collection_name: collection_name) or {
eprintln('Failed to delete collection: ${err}')
exit(1)
}
println('Collection deleted')
println('Example completed successfully')
)!
println('Collection Existence: ${collection_existence}')

View File

@@ -0,0 +1,206 @@
module qdrant
import freeflowuniverse.herolib.core.httpconnection
import json
// Configuration of the collection
pub struct CollectionConfig {
pub mut:
params CollectionParams // Collection parameters
hnsw_config HNSWConfig // HNSW configuration
optimizer_config OptimizerConfig // Optimizer configuration
wal_config WALConfig // WAL configuration
quantization_config ?QuantizationConfig // Optional quantization configuration, Nullable field
strict_mode_config StrictModeConfig // Strict mode configuration
}
// Parameters of the collection
pub struct CollectionParams {
pub mut:
vectors VectorConfig // Vector configuration
shard_number int // Number of shards
replication_factor int // Replication factor
write_consistency_factor int // Write consistency factor
on_disk_payload bool // On-disk payload
}
// Vector configuration
pub struct VectorConfig {
pub mut:
size int // Size of the vectors
distance string // Distance function
}
// HNSW (Hierarchical Navigable Small World) configuration
pub struct HNSWConfig {
pub mut:
m int // Number of neighbors
ef_construct int // Number of neighbors
full_scan_threshold int // Full scan threshold
max_indexing_threads int // Maximum indexing threads
on_disk bool // On-disk storage
}
// Optimizer configuration
pub struct OptimizerConfig {
pub mut:
deleted_threshold f64 // Deleted threshold
vacuum_min_vector_number int // Minimum vector number
default_segment_number int // Default segment number
max_segment_size ?int // Nullable field
memmap_threshold ?int // Nullable field
indexing_threshold int // Indexing threshold
flush_interval_sec int // Flush interval
max_optimization_threads ?int // Nullable field
}
// Write-Ahead Log (WAL) configuration
pub struct WALConfig {
pub mut:
wal_capacity_mb int // WAL capacity in megabytes
wal_segments_ahead int // WAL segments ahead
}
// Quantization configuration (nullable)
pub struct QuantizationConfig {
pub mut:
scalar ?ScalarQuantization // Nullable field
}
// Scalar quantization configuration
pub struct ScalarQuantization {
pub mut:
typ string @[json: 'type'] // Quantization type
}
// Strict mode configuration
pub struct StrictModeConfig {
pub mut:
enabled bool // Enabled
}
// Result field containing detailed information about the collection
pub struct GetCollectionResponse {
pub mut:
status string // Status
optimizer_status string // Optimizer status
indexed_vectors_count int // Indexed vectors count
points_count int // Points count
segments_count int // Segments count
config CollectionConfig // Collection configuration
payload_schema map[string]string // Payload schema
}
// Get a collection arguments
@[params]
pub struct GetCollectionParams {
pub mut:
collection_name string @[required] // Name of the collection
}
// Get a collection
pub fn (mut self QDrantClient) get_collection(params GetCollectionParams) !QDrantResponse[GetCollectionResponse] {
mut http_conn := self.httpclient()!
req := httpconnection.Request{
method: .get
prefix: '/collections/${params.collection_name}'
}
mut response := http_conn.get_json(req)!
println('response: ${response}')
return json.decode(QDrantResponse[GetCollectionResponse], response)!
}
// Create a collection arguments
@[params]
pub struct CreateCollectionParams {
pub mut:
collection_name string @[required] // Name of the collection
size int @[required] // Size of the vectors
distance string @[required] // Distance function
}
// Create a collection
pub fn (mut self QDrantClient) create_collection(params CreateCollectionParams) !QDrantResponse[bool] {
mut http_conn := self.httpclient()!
req := httpconnection.Request{
method: .put
prefix: '/collections/${params.collection_name}'
data: json.encode(VectorConfig{
size: params.size
distance: params.distance
})
}
mut response := http_conn.send(req)!
return json.decode(QDrantResponse[bool], response.data)!
}
// Delete a collection arguments
@[params]
pub struct DeleteCollectionParams {
pub mut:
collection_name string @[required] // Name of the collection
}
// Delete a collection
pub fn (mut self QDrantClient) delete_collection(params DeleteCollectionParams) !QDrantResponse[bool] {
mut http_conn := self.httpclient()!
req := httpconnection.Request{
method: .delete
prefix: '/collections/${params.collection_name}'
}
mut response := http_conn.send(req)!
return json.decode(QDrantResponse[bool], response.data)!
}
// Get a collection arguments
@[params]
pub struct ListCollectionParams {
collections []CollectionNameParams // List of collection names
}
// Get a collection arguments
@[params]
pub struct CollectionNameParams {
pub mut:
collection_name string @[json: 'name'; required] // Name of the collection
}
// List a collection
pub fn (mut self QDrantClient) list_collections() !QDrantResponse[ListCollectionParams] {
mut http_conn := self.httpclient()!
req := httpconnection.Request{
method: .get
prefix: '/collections'
}
mut response := http_conn.send(req)!
return json.decode(QDrantResponse[ListCollectionParams], response.data)!
}
// Check collection existence
pub struct CollectionExistenceResponse {
pub mut:
exists bool // Collection existence
}
// Check collection existence
@[params]
pub struct CollectionExistenceParams {
pub mut:
collection_name string @[json: 'name'; required] // Name of the collection
}
// Check collection existence
pub fn (mut self QDrantClient) is_exists(params CollectionExistenceParams) !QDrantResponse[CollectionExistenceResponse] {
mut http_conn := self.httpclient()!
req := httpconnection.Request{
method: .get
prefix: '/collections/${params.collection_name}/exists'
}
mut response := http_conn.send(req)!
return json.decode(QDrantResponse[CollectionExistenceResponse], response.data)!
}

View File

@@ -1,19 +1,26 @@
module qdrant
import freeflowuniverse.herolib.core.httpconnection
import json
// import os
// QdrantClient is the main client for interacting with the Qdrant API
pub struct QdrantClient {
// QDrant usage
pub struct QDrantUsage {
pub mut:
name string = 'default'
secret string
url string = 'http://localhost:6333'
cpu int // CPU usage
io_read int // I/O read usage
io_write int // I/O write usage
}
// Top-level response structure
pub struct QDrantResponse[T] {
pub mut:
usage QDrantUsage // Usage information
result T // The result
status string // Response status
time f64 // Response time
}
// httpclient creates a new HTTP connection to the Qdrant API
fn (mut self QdrantClient) httpclient() !&httpconnection.HTTPConnection {
fn (mut self QDrantClient) httpclient() !&httpconnection.HTTPConnection {
mut http_conn := httpconnection.new(
name: 'Qdrant_vclient'
url: self.url
@@ -21,374 +28,8 @@ fn (mut self QdrantClient) httpclient() !&httpconnection.HTTPConnection {
// Add authentication header if API key is provided
if self.secret.len > 0 {
http_conn.default_header.add(.api_key, self.secret)
http_conn.default_header.add_custom('api-key', self.secret)!
}
return http_conn
}
// Collections API
@[params]
pub struct CreateCollectionParams {
pub mut:
collection_name string @[required]
vectors VectorsConfig @[required]
shard_number ?int
replication_factor ?int
write_consistency_factor ?int
on_disk_payload ?bool
hnsw_config ?HnswConfig
optimizers_config ?OptimizersConfig
wal_config ?WalConfig
quantization_config ?QuantizationConfig
init_from ?InitFrom
timeout ?int
}
// Create a new collection
pub fn (mut q QdrantClient) create_collection(params CreateCollectionParams) !bool {
mut collection_params := CollectionParams{
vectors: params.vectors
}
if v := params.shard_number {
collection_params.shard_number = v
}
if v := params.replication_factor {
collection_params.replication_factor = v
}
if v := params.write_consistency_factor {
collection_params.write_consistency_factor = v
}
if v := params.on_disk_payload {
collection_params.on_disk_payload = v
}
if v := params.hnsw_config {
collection_params.hnsw_config = v
}
if v := params.optimizers_config {
collection_params.optimizers_config = v
}
if v := params.wal_config {
collection_params.wal_config = v
}
if v := params.quantization_config {
collection_params.quantization_config = v
}
if v := params.init_from {
collection_params.init_from = v
}
mut query_params := map[string]string{}
if v := params.timeout {
query_params['timeout'] = v.str()
}
req := httpconnection.Request{
method: .put
prefix: 'collections/${params.collection_name}'
dataformat: .json
data: json.encode(collection_params)
params: query_params
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
result := json.decode(OperationResponse, response.body)!
return result.result
}
@[params]
pub struct ListCollectionsParams {
pub mut:
timeout ?int
}
// List all collections
pub fn (mut q QdrantClient) list_collections(params ListCollectionsParams) !CollectionsResponse {
mut query_params := map[string]string{}
if v := params.timeout {
query_params['timeout'] = v.str()
}
req := httpconnection.Request{
method: .get
prefix: 'collections'
params: query_params
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
return json.decode(CollectionsResponse, response.body)!
}
@[params]
pub struct DeleteCollectionParams {
pub mut:
collection_name string @[required]
timeout ?int
}
// Delete a collection
pub fn (mut q QdrantClient) delete_collection(params DeleteCollectionParams) !bool {
mut query_params := map[string]string{}
if v := params.timeout {
query_params['timeout'] = v.str()
}
req := httpconnection.Request{
method: .delete
prefix: 'collections/${params.collection_name}'
params: query_params
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
result := json.decode(OperationResponse, response.body)!
return result.result
}
@[params]
pub struct GetCollectionParams {
pub mut:
collection_name string @[required]
timeout ?int
}
// Get collection info
pub fn (mut q QdrantClient) get_collection(params GetCollectionParams) !CollectionInfo {
mut query_params := map[string]string{}
if v := params.timeout {
query_params['timeout'] = v.str()
}
req := httpconnection.Request{
method: .get
prefix: 'collections/${params.collection_name}'
params: query_params
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
result := json.decode(CollectionInfoResponse, response.body)!
return result.result
}
// Points API
@[params]
pub struct UpsertPointsParams {
pub mut:
collection_name string @[required]
points []PointStruct @[required]
wait ?bool
ordering ?WriteOrdering
}
// Upsert points
pub fn (mut q QdrantClient) upsert_points(params UpsertPointsParams) !PointsOperationResponse {
mut query_params := map[string]string{}
if v := params.wait {
query_params['wait'] = v.str()
}
mut request_body := map[string]json.Any{}
request_body['points'] = params.points
if v := params.ordering {
request_body['ordering'] = v
}
req := httpconnection.Request{
method: .put
prefix: 'collections/${params.collection_name}/points'
dataformat: .json
data: json.encode(request_body)
params: query_params
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
return json.decode(PointsOperationResponse, response.body)!
}
@[params]
pub struct DeletePointsParams {
pub mut:
collection_name string @[required]
points_selector PointsSelector @[required]
wait ?bool
ordering ?WriteOrdering
}
// Delete points
pub fn (mut q QdrantClient) delete_points(params DeletePointsParams) !PointsOperationResponse {
mut query_params := map[string]string{}
if v := params.wait {
query_params['wait'] = v.str()
}
mut request_body := map[string]json.Any{}
if params.points_selector.points != none {
request_body['points'] = params.points_selector.points
} else if params.points_selector.filter != none {
request_body['filter'] = params.points_selector.filter
}
if v := params.ordering {
request_body['ordering'] = v
}
req := httpconnection.Request{
method: .post
prefix: 'collections/${params.collection_name}/points/delete'
dataformat: .json
data: json.encode(request_body)
params: query_params
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
return json.decode(PointsOperationResponse, response.body)!
}
@[params]
pub struct GetPointParams {
pub mut:
collection_name string @[required]
id string @[required]
with_payload ?WithPayloadSelector
with_vector ?WithVector
}
// Get a point by ID
pub fn (mut q QdrantClient) get_point(params GetPointParams) !GetPointResponse {
mut query_params := map[string]string{}
if v := params.with_payload {
query_params['with_payload'] = json.encode(v)
}
if v := params.with_vector {
query_params['with_vector'] = json.encode(v)
}
req := httpconnection.Request{
method: .get
prefix: 'collections/${params.collection_name}/points/${params.id}'
params: query_params
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
return json.decode(GetPointResponse, response.body)!
}
@[params]
pub struct SearchParams {
pub mut:
collection_name string @[required]
vector []f32 @[required]
limit int = 10
filter ?Filter
params ?SearchParamsConfig
with_payload ?WithPayloadSelector
with_vector ?WithVector
score_threshold ?f32
}
// Search for points
pub fn (mut q QdrantClient) search(params SearchParams) !SearchResponse {
// Create a struct to serialize to JSON
struct SearchRequest {
pub mut:
vector []f32
limit int
filter ?Filter
params ?SearchParamsConfig
with_payload ?WithPayloadSelector
with_vector ?WithVector
score_threshold ?f32
}
mut request := SearchRequest{
vector: params.vector
limit: params.limit
}
if v := params.filter {
request.filter = v
}
if v := params.params {
request.params = v
}
if v := params.with_payload {
request.with_payload = v
}
if v := params.with_vector {
request.with_vector = v
}
if v := params.score_threshold {
request.score_threshold = v
}
req := httpconnection.Request{
method: .post
prefix: 'collections/${params.collection_name}/points/search'
dataformat: .json
data: json.encode(request)
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
return json.decode(SearchResponse, response.data)!
}
// Service API
// Get Qdrant service info
pub fn (mut q QdrantClient) get_service_info() !ServiceInfoResponse {
req := httpconnection.Request{
method: .get
prefix: ''
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
return json.decode(ServiceInfoResponse, response.data)!
}
// Check Qdrant health
pub fn (mut q QdrantClient) health_check() !bool {
req := httpconnection.Request{
method: .get
prefix: 'healthz'
}
mut httpclient := q.httpclient()!
response := httpclient.send(req)!
return response.code == 200
}

View File

@@ -1,117 +1 @@
module qdrant
fn test_qdrant_client() {
mut client := QDrantClient{
name: 'test_client'
url: 'http://localhost:6333'
}
// Test creating a collection
vectors_config := VectorsConfig{
size: 128
distance: .cosine
}
// Create collection
create_result := client.create_collection(
collection_name: 'test_collection'
vectors: vectors_config
) or {
assert false, 'Failed to create collection: ${err}'
return
}
assert create_result == true
// List collections
collections := client.list_collections() or {
assert false, 'Failed to list collections: ${err}'
return
}
assert 'test_collection' in collections.result
// Get collection info
collection_info := client.get_collection(
collection_name: 'test_collection'
) or {
assert false, 'Failed to get collection info: ${err}'
return
}
assert collection_info.vectors_count == 0
// Upsert points
points := [
PointStruct{
id: '1'
vector: [f32(0.1), 0.2, 0.3, 0.4]
payload: {
'color': 'red'
'category': 'furniture'
}
},
PointStruct{
id: '2'
vector: [f32(0.2), 0.3, 0.4, 0.5]
payload: {
'color': 'blue'
'category': 'electronics'
}
}
]
upsert_result := client.upsert_points(
collection_name: 'test_collection'
points: points
wait: true
) or {
assert false, 'Failed to upsert points: ${err}'
return
}
assert upsert_result.status == 'ok'
// Search for points
search_result := client.search(
collection_name: 'test_collection'
vector: [f32(0.1), 0.2, 0.3, 0.4]
limit: 1
) or {
assert false, 'Failed to search points: ${err}'
return
}
assert search_result.result.len > 0
// Get a point
point := client.get_point(
collection_name: 'test_collection'
id: '1'
) or {
assert false, 'Failed to get point: ${err}'
return
}
if result := point.result {
assert result.id == '1'
} else {
assert false, 'Point not found'
}
// Delete a point
delete_result := client.delete_points(
collection_name: 'test_collection'
points_selector: PointsSelector{
points: ['1']
}
wait: true
) or {
assert false, 'Failed to delete point: ${err}'
return
}
assert delete_result.status == 'ok'
// Delete collection
delete_collection_result := client.delete_collection(
collection_name: 'test_collection'
) or {
assert false, 'Failed to delete collection: ${err}'
return
}
assert delete_collection_result == true
}

View File

@@ -36,362 +36,362 @@ pub fn heroscript_loads(heroscript string) !QDrantClient {
return obj
}
// Base response structure
pub struct BaseResponse {
pub mut:
time f32
status string
}
// // Base response structure
// pub struct BaseResponse {
// pub mut:
// time f32
// status string
// }
// Operation response
pub struct OperationResponse {
pub mut:
time f32
status string
result bool
}
// // Operation response
// pub struct OperationResponse {
// pub mut:
// time f32
// status string
// result bool
// }
// Collections response
pub struct CollectionsResponse {
pub mut:
time f32
status string
result []string
}
// // Collections response
// pub struct CollectionsResponse {
// pub mut:
// time f32
// status string
// result []string
// }
// Collection info response
pub struct CollectionInfoResponse {
pub mut:
time f32
status string
result CollectionInfo
}
// // Collection info response
// pub struct CollectionInfoResponse {
// pub mut:
// time f32
// status string
// result CollectionInfo
// }
// Collection info
pub struct CollectionInfo {
pub mut:
status string
optimizer_status OptimizersStatus
vectors_count u64
indexed_vectors_count ?u64
points_count u64
segments_count u64
config CollectionConfig
payload_schema map[string]PayloadIndexInfo
}
// // Collection info
// pub struct CollectionInfo {
// pub mut:
// status string
// optimizer_status OptimizersStatus
// vectors_count u64
// indexed_vectors_count ?u64
// points_count u64
// segments_count u64
// config CollectionConfig
// payload_schema map[string]PayloadIndexInfo
// }
// Optimizers status
pub struct OptimizersStatus {
pub mut:
status string
}
// // Optimizers status
// pub struct OptimizersStatus {
// pub mut:
// status string
// }
// Collection config
pub struct CollectionConfig {
pub mut:
params CollectionParams
hnsw_config ?HnswConfig
optimizer_config ?OptimizersConfig
wal_config ?WalConfig
quantization_config ?QuantizationConfig
}
// // Collection config
// pub struct CollectionConfig {
// pub mut:
// params CollectionParams
// hnsw_config ?HnswConfig
// optimizer_config ?OptimizersConfig
// wal_config ?WalConfig
// quantization_config ?QuantizationConfig
// }
// Collection params
pub struct CollectionParams {
pub mut:
vectors VectorsConfig
shard_number ?int
replication_factor ?int
write_consistency_factor ?int
on_disk_payload ?bool
hnsw_config ?HnswConfig
optimizers_config ?OptimizersConfig
wal_config ?WalConfig
quantization_config ?QuantizationConfig
init_from ?InitFrom
}
// // Collection params
// pub struct CollectionParams {
// pub mut:
// vectors VectorsConfig
// shard_number ?int
// replication_factor ?int
// write_consistency_factor ?int
// on_disk_payload ?bool
// hnsw_config ?HnswConfig
// optimizers_config ?OptimizersConfig
// wal_config ?WalConfig
// quantization_config ?QuantizationConfig
// init_from ?InitFrom
// }
// Vectors config
pub struct VectorsConfig {
pub mut:
size int
distance Distance
hnsw_config ?HnswConfig
quantization_config ?QuantizationConfig
on_disk ?bool
}
// // Vectors config
// pub struct VectorsConfig {
// pub mut:
// size int
// distance Distance
// hnsw_config ?HnswConfig
// quantization_config ?QuantizationConfig
// on_disk ?bool
// }
// Distance type
pub enum Distance {
cosine
euclid
dot
}
// // Distance type
// pub enum Distance {
// cosine
// euclid
// dot
// }
// Convert Distance enum to string
pub fn (d Distance) str() string {
return match d {
.cosine { 'cosine' }
.euclid { 'euclid' }
.dot { 'dot' }
}
}
// // Convert Distance enum to string
// pub fn (d Distance) str() string {
// return match d {
// .cosine { 'cosine' }
// .euclid { 'euclid' }
// .dot { 'dot' }
// }
// }
// HNSW config
pub struct HnswConfig {
pub mut:
m int
ef_construct int
full_scan_threshold ?int
max_indexing_threads ?int
on_disk ?bool
payload_m ?int
}
// // HNSW config
// pub struct HnswConfig {
// pub mut:
// m int
// ef_construct int
// full_scan_threshold ?int
// max_indexing_threads ?int
// on_disk ?bool
// payload_m ?int
// }
// Optimizers config
pub struct OptimizersConfig {
pub mut:
deleted_threshold f32
vacuum_min_vector_number int
default_segment_number int
max_segment_size ?int
memmap_threshold ?int
indexing_threshold ?int
flush_interval_sec ?int
max_optimization_threads ?int
}
// // Optimizers config
// pub struct OptimizersConfig {
// pub mut:
// deleted_threshold f32
// vacuum_min_vector_number int
// default_segment_number int
// max_segment_size ?int
// memmap_threshold ?int
// indexing_threshold ?int
// flush_interval_sec ?int
// max_optimization_threads ?int
// }
// WAL config
pub struct WalConfig {
pub mut:
wal_capacity_mb ?int
wal_segments_ahead ?int
}
// // WAL config
// pub struct WalConfig {
// pub mut:
// wal_capacity_mb ?int
// wal_segments_ahead ?int
// }
// Quantization config
pub struct QuantizationConfig {
pub mut:
scalar ?ScalarQuantization
product ?ProductQuantization
binary ?BinaryQuantization
}
// // Quantization config
// pub struct QuantizationConfig {
// pub mut:
// scalar ?ScalarQuantization
// product ?ProductQuantization
// binary ?BinaryQuantization
// }
// Scalar quantization
pub struct ScalarQuantization {
pub mut:
type_ string
quantile ?f32
always_ram ?bool
}
// // Scalar quantization
// pub struct ScalarQuantization {
// pub mut:
// type_ string
// quantile ?f32
// always_ram ?bool
// }
// Product quantization
pub struct ProductQuantization {
pub mut:
compression string
always_ram ?bool
}
// // Product quantization
// pub struct ProductQuantization {
// pub mut:
// compression string
// always_ram ?bool
// }
// Binary quantization
pub struct BinaryQuantization {
pub mut:
binary bool
always_ram ?bool
}
// // Binary quantization
// pub struct BinaryQuantization {
// pub mut:
// binary bool
// always_ram ?bool
// }
// Init from
pub struct InitFrom {
pub mut:
collection string
shard ?int
}
// // Init from
// pub struct InitFrom {
// pub mut:
// collection string
// shard ?int
// }
// Payload index info
pub struct PayloadIndexInfo {
pub mut:
data_type string
params ?map[string]string
points int
}
// // Payload index info
// pub struct PayloadIndexInfo {
// pub mut:
// data_type string
// params ?map[string]string
// points int
// }
// Points operation response
pub struct PointsOperationResponse {
pub mut:
time f32
status string
result OperationInfo
}
// // Points operation response
// pub struct PointsOperationResponse {
// pub mut:
// time f32
// status string
// result OperationInfo
// }
// Operation info
pub struct OperationInfo {
pub mut:
operation_id int
status string
}
// // Operation info
// pub struct OperationInfo {
// pub mut:
// operation_id int
// status string
// }
// Point struct
pub struct PointStruct {
pub mut:
id string
vector []f32
payload ?map[string]string
}
// // Point struct
// pub struct PointStruct {
// pub mut:
// id string
// vector []f32
// payload ?map[string]string
// }
// Points selector
pub struct PointsSelector {
pub mut:
points ?[]string
filter ?Filter
}
// // Points selector
// pub struct PointsSelector {
// pub mut:
// points ?[]string
// filter ?Filter
// }
// Filter
pub struct Filter {
pub mut:
must ?[]Condition
must_not ?[]Condition
should ?[]Condition
}
// // Filter
// pub struct Filter {
// pub mut:
// must ?[]Condition
// must_not ?[]Condition
// should ?[]Condition
// }
// Filter is serialized directly to JSON
// // Filter is serialized directly to JSON
// Condition interface
pub interface Condition {}
// // Condition interface
// pub interface Condition {}
// Field condition
pub struct FieldCondition {
pub mut:
key string
match ?string @[json: match]
match_integer ?int @[json: match]
match_float ?f32 @[json: match]
match_bool ?bool @[json: match]
range ?Range
geo_bounding_box ?GeoBoundingBox
geo_radius ?GeoRadius
values_count ?ValuesCount
}
// // Field condition
// pub struct FieldCondition {
// pub mut:
// key string
// match ?string @[json: match]
// match_integer ?int @[json: match]
// match_float ?f32 @[json: match]
// match_bool ?bool @[json: match]
// range ?Range
// geo_bounding_box ?GeoBoundingBox
// geo_radius ?GeoRadius
// values_count ?ValuesCount
// }
// FieldCondition is serialized directly to JSON
// // FieldCondition is serialized directly to JSON
// Range
pub struct Range {
pub mut:
lt ?f32
gt ?f32
gte ?f32
lte ?f32
}
// // Range
// pub struct Range {
// pub mut:
// lt ?f32
// gt ?f32
// gte ?f32
// lte ?f32
// }
// Range is serialized directly to JSON
// // Range is serialized directly to JSON
// GeoBoundingBox
pub struct GeoBoundingBox {
pub mut:
top_left GeoPoint
bottom_right GeoPoint
}
// // GeoBoundingBox
// pub struct GeoBoundingBox {
// pub mut:
// top_left GeoPoint
// bottom_right GeoPoint
// }
// GeoBoundingBox is serialized directly to JSON
// // GeoBoundingBox is serialized directly to JSON
// GeoPoint
pub struct GeoPoint {
pub mut:
lon f32
lat f32
}
// // GeoPoint
// pub struct GeoPoint {
// pub mut:
// lon f32
// lat f32
// }
// GeoPoint is serialized directly to JSON
// // GeoPoint is serialized directly to JSON
// GeoRadius
pub struct GeoRadius {
pub mut:
center GeoPoint
radius f32
}
// // GeoRadius
// pub struct GeoRadius {
// pub mut:
// center GeoPoint
// radius f32
// }
// GeoRadius is serialized directly to JSON
// // GeoRadius is serialized directly to JSON
// ValuesCount
pub struct ValuesCount {
pub mut:
lt ?int
gt ?int
gte ?int
lte ?int
}
// // ValuesCount
// pub struct ValuesCount {
// pub mut:
// lt ?int
// gt ?int
// gte ?int
// lte ?int
// }
// ValuesCount is serialized directly to JSON
// // ValuesCount is serialized directly to JSON
// WithPayloadSelector
pub struct WithPayloadSelector {
pub mut:
include ?[]string
exclude ?[]string
}
// // WithPayloadSelector
// pub struct WithPayloadSelector {
// pub mut:
// include ?[]string
// exclude ?[]string
// }
// WithPayloadSelector is serialized directly to JSON
// // WithPayloadSelector is serialized directly to JSON
// WithVector
pub struct WithVector {
pub mut:
include ?[]string
}
// // WithVector
// pub struct WithVector {
// pub mut:
// include ?[]string
// }
// WithVector is serialized directly to JSON
// // WithVector is serialized directly to JSON
// Get point response
pub struct GetPointResponse {
pub mut:
time f32
status string
result ?PointStruct
}
// // Get point response
// pub struct GetPointResponse {
// pub mut:
// time f32
// status string
// result ?PointStruct
// }
// Search params configuration
pub struct SearchParamsConfig {
pub mut:
hnsw_ef ?int
exact ?bool
}
// // Search params configuration
// pub struct SearchParamsConfig {
// pub mut:
// hnsw_ef ?int
// exact ?bool
// }
// SearchParamsConfig is serialized directly to JSON
// // SearchParamsConfig is serialized directly to JSON
// Search response
pub struct SearchResponse {
pub mut:
time f32
status string
result []ScoredPoint
}
// // Search response
// pub struct SearchResponse {
// pub mut:
// time f32
// status string
// result []ScoredPoint
// }
// Scored point
pub struct ScoredPoint {
pub mut:
id string
version int
score f32
payload ?map[string]string
vector ?[]f32
}
// // Scored point
// pub struct ScoredPoint {
// pub mut:
// id string
// version int
// score f32
// payload ?map[string]string
// vector ?[]f32
// }
// Write ordering
pub struct WriteOrdering {
pub mut:
type_ string
}
// // Write ordering
// pub struct WriteOrdering {
// pub mut:
// type_ string
// }
// WriteOrdering is serialized directly to JSON
// // WriteOrdering is serialized directly to JSON
// Service info response
pub struct ServiceInfoResponse {
pub mut:
time f32
status string
result ServiceInfo
}
// // Service info response
// pub struct ServiceInfoResponse {
// pub mut:
// time f32
// status string
// result ServiceInfo
// }
// Service info
pub struct ServiceInfo {
pub mut:
version string
commit ?string
}
// // Service info
// pub struct ServiceInfo {
// pub mut:
// version string
// commit ?string
// }

View File

@@ -1,13 +1,14 @@
module qdrant
import os
import freeflowuniverse.herolib.data.encoderhero
import freeflowuniverse.herolib.core.pathlib
import freeflowuniverse.herolib.ui.console
pub const version = '1.13.4'
const singleton = false
const default = true
// THIS THE THE SOURCE OF THE INFORMATION OF THIS FILE, HERE WE HAVE THE CONFIG OBJECT CONFIGURED AND MODELLED
@[heap]
pub struct QDrant {
@@ -31,9 +32,9 @@ fn obj_init(mycfg_ QDrant) !QDrant {
// called before start if done
fn configure() ! {
mut installer := get()!
storage_path:="${os.home_dir()}/hero/var/qdrant"
storage_path := '${os.home_dir()}/hero/var/qdrant'
mut mycode := $tmpl('templates/config.yaml')
mut path := pathlib.get_file(path: "${os.home_dir()}/hero/var/qdrant/config.yaml", create: true)!
mut path := pathlib.get_file(path: '${os.home_dir()}/hero/var/qdrant/config.yaml', create: true)!
path.write(mycode)!
// console.print_debug(mycode)
}