Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ai Qdrant Store Laravel Package

symfony/ai-qdrant-store

Qdrant Store integrates the Qdrant vector database with Symfony AI Store, enabling you to manage collections and points and run unified vector search with filters. Provides a Symfony-friendly bridge to Qdrant for embedding-based retrieval use cases.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package:

    composer require symfony/ai-qdrant-store
    
  2. Configure Qdrant Store in config/packages/ai.yaml:

    framework:
        ai:
            stores:
                qdrant:
                    type: qdrant
                    url: '%env(QDRANT_API_URL)%'  # e.g., http://localhost:6333
                    api_key: '%env(QDRANT_API_KEY)%'  # Optional if using auth
                    collection: 'your_collection_name'
                    options:
                        # Optional Qdrant client options
                        timeout: 30
                        retries: 3
    
  3. First Use Case: Vector Storage & Search Inject the store via dependency injection and use it for basic operations:

    use Symfony\AI\Store\StoreInterface;
    
    class DocumentService {
        public function __construct(
            private StoreInterface $qdrantStore
        ) {}
    
        public function storeDocument(array $embedding, string $documentId): void {
            $this->qdrantStore->upsert([
                [
                    'id' => $documentId,
                    'vector' => $embedding,
                    'payload' => ['content' => '...', 'metadata' => [...]],
                ],
            ]);
        }
    
        public function findSimilarDocuments(array $queryEmbedding, int $limit = 5): array {
            return $this->qdrantStore->search($queryEmbedding, limit: $limit);
        }
    }
    
  4. Verify Collection Exists The store will auto-create the collection on first use. Check Qdrant’s dashboard or API:

    curl -X GET http://localhost:6333/collections/your_collection_name
    

Implementation Patterns

Core Workflows

1. Vector CRUD Operations

  • Upsert (Insert/Update):
    $this->qdrantStore->upsert([
        [
            'id' => 'doc_123',
            'vector' => [0.1, 0.2, ...], // Your embedding
            'payload' => ['title' => 'Example', 'tags' => ['ai', 'search']],
        ],
    ]);
    
  • Delete by ID:
    $this->qdrantStore->remove(['doc_123']);
    
  • Bulk Operations:
    $this->qdrantStore->upsert(array_map(fn($doc) => [
        'id' => $doc['id'],
        'vector' => $doc['embedding'],
        'payload' => $doc['metadata'],
    ], $documents));
    

2. Semantic Search with Filtering

Combine vector similarity with metadata filtering:

$results = $this->qdrantStore->search(
    [0.15, 0.25, ...], // Query embedding
    limit: 10,
    filter: [
        'must' => [
            ['key' => 'status', 'match' => ['value' => 'published']],
            ['key' => 'tags', 'match' => ['any' => ['ai']]],
        ],
    ]
);
  • Filter Syntax: Use Qdrant’s filter syntax (e.g., must, should, range).

3. Batch Processing with Symfony Components

Leverage Symfony’s Messenger for async operations:

use Symfony\Component\Messenger\MessageBusInterface;

class EmbeddingProcessor {
    public function __construct(
        private StoreInterface $qdrantStore,
        private MessageBusInterface $bus
    ) {}

    public function processDocuments(array $documents): void {
        $this->bus->dispatch(new ProcessEmbeddingsMessage($documents));
    }
}

// In a worker:
$handler = new class implements MessageHandlerInterface {
    public function __invoke(ProcessEmbeddingsMessage $message) {
        $this->qdrantStore->upsert($message->getEmbeddings());
    }
};

4. Hybrid AI Pipelines

Combine with Symfony AI’s EmbeddingGenerator:

use Symfony\AI\EmbeddingGeneratorInterface;

class SearchService {
    public function __construct(
        private EmbeddingGeneratorInterface $embeddingGenerator,
        private StoreInterface $qdrantStore
    ) {}

    public function semanticSearch(string $query, int $limit = 5): array {
        $embedding = $this->embeddingGenerator->generate($query);
        return $this->qdrantStore->search($embedding, limit: $limit);
    }
}

Integration Tips

1. Configuration Management

  • Use environment variables for sensitive data:
    # .env
    QDRANT_API_URL=http://localhost:6333
    QDRANT_API_KEY=your_api_key
    
  • Dynamically set collection names:
    $store = new QdrantStore(
        new QdrantClient($url, $apiKey),
        'collection_' . $tenantId
    );
    

2. Error Handling

Wrap operations in try-catch blocks:

try {
    $this->qdrantStore->upsert($points);
} catch (\Symfony\AI\Exception\StoreException $e) {
    // Log or retry
    $this->logger->error('Qdrant upsert failed', ['error' => $e->getMessage()]);
    throw new \RuntimeException('Failed to store embeddings', 0, $e);
}

3. Performance Optimization

  • Batch Size: Optimize for Qdrant’s batch limits (typically 100–1000 points per request).
  • Vector Dimensions: Ensure consistency in vector size across all operations.
  • Caching: Cache frequent queries:
    use Symfony\Component\Cache\Adapter\RedisAdapter;
    
    $cache = RedisAdapter::createConnection('redis://localhost');
    $cachedResults = $cache->get('search_results_' . md5(serialize($query)));
    if (!$cachedResults) {
        $cachedResults = $this->qdrantStore->search($query);
        $cache->set('search_results_' . md5(serialize($query)), $cachedResults, 3600);
    }
    

4. Testing

  • Use a test container for Qdrant:
    use Symfony\Component\Process\Process;
    
    $process = new Process(['docker', 'run', '-d', '-p', '6333:6333', 'qdrant/qdrant']);
    $process->start();
    
  • Mock the store in unit tests:
    $mockStore = $this->createMock(StoreInterface::class);
    $mockStore->method('search')->willReturn([...]);
    

5. Schema Management

Define collection schema upfront (e.g., in a CollectionInitializer service):

use Qdrant\Client\QdrantClient;

class CollectionInitializer {
    public function __construct(private QdrantClient $client) {}

    public function initialize(string $collectionName): void {
        $this->client->recreateCollection($collectionName, [
            'vectors' => [
                'size' => 768, // Dimension of your embeddings
                'distance' => 'Cosine', // or 'Dot', 'Euclidean'
            ],
            'payload_schema' => [
                'title' => new \stdClass(), // String field
                'tags' => new \stdClass(),  // Array of strings
                'status' => new \stdClass(), // String enum
            ],
        ]);
    }
}

Gotchas and Tips

Pitfalls

1. Collection Auto-Creation

  • Issue: The store auto-creates collections on first use, which may not match your schema expectations.
  • Fix: Explicitly initialize collections with the correct schema (see Schema Management above).

2. Vector Dimension Mismatch

  • Issue: Qdrant will reject operations if vector dimensions don’t match the collection’s schema.
  • Fix: Validate dimensions before upserting:
    if (count($vector) !== 768) {
        throw new \InvalidArgumentException('Vector must be 768 dimensions');
    }
    

3. Filter Syntax Errors

  • Issue: Qdrant’s filter syntax is strict. Invalid filters (e.g., wrong key names) will fail silently or return empty results.
  • Fix: Test filters in Qdrant’s playground first.

4. Rate Limiting

  • Issue: Cloud Qdrant may throttle requests. Self-hosted instances can also hit resource limits.
  • Fix:
    • Use ScopingHttpClient with retries:
      $httpClient = new ScopingHttpClient(
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi