ChunkSearchService.php

Code Hygiene Score: 100

Keine Issues gefunden.

Dependencies 4

Klassen 1

Funktionen 4

Verwendet von 5

Code

<?php

declare(strict_types=1);

namespace Infrastructure\Docs;

// @responsibility: Semantische Suche in Dokumentations-Chunks via Qdrant

use Infrastructure\AI\OllamaService;
use Infrastructure\AI\QdrantClient;

final class ChunkSearchService
{
    private const string COLLECTION = 'dokumentation_chunks';

    public function __construct(
        private QdrantClient $qdrant,
        private OllamaService $ollama
    ) {
    }

    /**
     * Searches for similar chunks using semantic search.
     *
     * @param array<string, mixed>|null $filter Optional filter for taxonomy/entities
     * @return array<array{id: int, doc_id: int, path: string, title: string, content: string, score: float, taxonomy: array<string>, entities: array<mixed>}>
     */
    public function search(string $query, int $limit = 5, ?array $filter = null): array
    {
        $embedding = $this->ollama->getEmbedding($query);

        $results = $this->qdrant->search(self::COLLECTION, $embedding, $limit, $filter);

        return array_map(static function (array $item): array {
            $payload = $item['payload'] ?? [];

            return [
                'id' => (int) ($payload['chunk_id'] ?? 0),
                'doc_id' => (int) ($payload['doc_id'] ?? 0),
                'path' => (string) ($payload['path'] ?? ''),
                'title' => (string) ($payload['title'] ?? ''),
                'content' => (string) ($payload['content_preview'] ?? ''),
                'score' => (float) ($item['score'] ?? 0),
                'taxonomy' => is_array($payload['taxonomy'] ?? null) ? $payload['taxonomy'] : [],
                'entities' => is_array($payload['entities'] ?? null) ? $payload['entities'] : [],
            ];
        }, $results);
    }

    /**
     * Searches with taxonomy filter.
     *
     * @return array<array<string, mixed>>
     */
    public function searchByTaxonomy(string $query, string $category, int $limit = 5): array
    {
        $filter = [
            'must' => [
                [
                    'key' => 'taxonomy_category',
                    'match' => ['value' => $category],
                ],
            ],
        ];

        return $this->search($query, $limit, $filter);
    }

    /**
     * Gets collection statistics.
     *
     * @return array{points_count: int, status: string}|null
     */
    public function getStats(): ?array
    {
        return $this->qdrant->getCollectionStats(self::COLLECTION);
    }
}
← Übersicht Graph