Backup #2068
| ID | 2068 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/UseCases/Search/EnhancedSearchUseCase.php |
| Version | 4 |
| Typ |
modified |
| Größe | 7.2 KB |
| Hash | 18d43925b949fc6f2d37d4e1cd4bb1fe8252c52a2db6553d1ba88d9c6f75db90 |
| Datum | 2025-12-28 23:32:02 |
| Geändert von | claude-code-hook |
| Grund | Claude Code Pre-Hook Backup vor Edit-Operation |
| Datei existiert |
Ja
|
Dateiinhalt
<?php
declare(strict_types=1);
namespace UseCases\Search;
// @responsibility: Erweiterte Suche mit Taxonomie-Term-ID-Filterung
use Domain\Repository\ChunkTaxonomyRepositoryInterface;
use Domain\Repository\TaxonomyRepositoryInterface;
use Domain\Service\SearchServiceInterface;
final class EnhancedSearchUseCase
{
public function __construct(
private SearchServiceInterface $searchService,
private ChunkTaxonomyRepositoryInterface $chunkTaxonomyRepository,
private TaxonomyRepositoryInterface $taxonomyRepository
) {
}
/**
* Enhanced search with taxonomy term ID filtering.
*
* @param string $query Search query
* @param array<int> $taxonomyTermIds Filter by these taxonomy term IDs
* @param bool $includeChildTerms Include child terms in filter (recursive)
* @param int $limit Maximum results
* @return array{
* results: array<array<string, mixed>>,
* taxonomy_filter: array{term_ids: array<int>, chunk_ids: array<int>},
* total_before_filter: int,
* total_after_filter: int
* }
*/
public function execute(
string $query,
array $taxonomyTermIds = [],
bool $includeChildTerms = false,
int $limit = 10
): array {
// If no taxonomy filter, delegate directly to search service
if (empty($taxonomyTermIds)) {
$results = $this->searchService->search($query, [], $limit);
return [
'results' => $results,
'taxonomy_filter' => ['term_ids' => [], 'chunk_ids' => []],
'total_before_filter' => count($results),
'total_after_filter' => count($results),
];
}
// Expand term IDs if includeChildTerms is true
$effectiveTermIds = $includeChildTerms
? $this->expandWithChildTerms($taxonomyTermIds)
: $taxonomyTermIds;
// Get chunk IDs that match the taxonomy filter
$filteredChunkIds = $this->getChunkIdsForTerms($effectiveTermIds);
if (empty($filteredChunkIds)) {
return [
'results' => [],
'taxonomy_filter' => ['term_ids' => $effectiveTermIds, 'chunk_ids' => []],
'total_before_filter' => 0,
'total_after_filter' => 0,
];
}
// Perform search with higher limit to allow for filtering
$searchResults = $this->searchService->search($query, [], $limit * 5);
$totalBeforeFilter = count($searchResults);
// Filter results to only include chunks matching taxonomy
$filteredResults = array_filter(
$searchResults,
static fn (array $result): bool => in_array($result['chunk_id'] ?? 0, $filteredChunkIds, true)
);
// Re-index and limit
$filteredResults = array_values($filteredResults);
$limitedResults = array_slice($filteredResults, 0, $limit);
return [
'results' => $limitedResults,
'taxonomy_filter' => [
'term_ids' => $effectiveTermIds,
'chunk_ids' => $filteredChunkIds,
],
'total_before_filter' => $totalBeforeFilter,
'total_after_filter' => count($filteredResults),
];
}
/**
* Search within a specific taxonomy term and its children.
*
* @return array<array<string, mixed>>
*/
public function searchInTaxonomy(string $query, int $termId, int $limit = 10): array
{
$result = $this->execute($query, [$termId], true, $limit);
return $result['results'];
}
/**
* Get search suggestions based on taxonomy structure.
*
* @return array{
* terms: array<array{id: int, name: string, chunk_count: int}>,
* suggested_filters: array<int>
* }
*/
public function getSuggestionsForQuery(string $query): array
{
// First, get search results without filter
$results = $this->searchService->search($query, [], 20);
if (empty($results)) {
return ['terms' => [], 'suggested_filters' => []];
}
// Extract chunk IDs from results
$chunkIds = array_map(
static fn (array $r): int => (int) ($r['chunk_id'] ?? 0),
$results
);
$chunkIds = array_filter($chunkIds);
// Find common taxonomy terms for these chunks
$termCounts = [];
foreach ($chunkIds as $chunkId) {
$mappings = $this->chunkTaxonomyRepository->findByChunkId($chunkId);
foreach ($mappings as $mapping) {
$termId = $mapping->getTaxonomyTermId();
if (!isset($termCounts[$termId])) {
$termCounts[$termId] = 0;
}
$termCounts[$termId]++;
}
}
// Sort by count and get top terms
arsort($termCounts);
$topTermIds = array_slice(array_keys($termCounts), 0, 5);
// Get term details
$terms = [];
foreach ($topTermIds as $termId) {
$term = $this->taxonomyRepository->find($termId);
if ($term !== null) {
$terms[] = [
'id' => $termId,
'name' => $term['name'],
'chunk_count' => $termCounts[$termId],
];
}
}
return [
'terms' => $terms,
'suggested_filters' => $topTermIds,
];
}
/**
* Expand term IDs to include all child terms.
*
* @param array<int> $termIds
* @return array<int>
*/
private function expandWithChildTerms(array $termIds): array
{
$allTerms = $this->taxonomyRepository->findAll();
$expanded = $termIds;
// Build parent-child map
$childrenMap = [];
foreach ($allTerms as $term) {
$parentId = $term['parent_id'];
if ($parentId !== null) {
if (!isset($childrenMap[$parentId])) {
$childrenMap[$parentId] = [];
}
$childrenMap[$parentId][] = $term['id'];
}
}
// Recursively add children
$queue = $termIds;
while (!empty($queue)) {
$currentId = array_shift($queue);
if (isset($childrenMap[$currentId])) {
foreach ($childrenMap[$currentId] as $childId) {
if (!in_array($childId, $expanded, true)) {
$expanded[] = $childId;
$queue[] = $childId;
}
}
}
}
return $expanded;
}
/**
* Get chunk IDs that have mappings to any of the given taxonomy terms.
*
* @param array<int> $termIds
* @return array<int>
*/
private function getChunkIdsForTerms(array $termIds): array
{
$chunkIds = [];
foreach ($termIds as $termId) {
$mappings = $this->chunkTaxonomyRepository->findByTaxonomyTermId($termId);
foreach ($mappings as $mapping) {
$chunkId = $mapping['chunk_id'];
if ($chunkId > 0 && !in_array($chunkId, $chunkIds, true)) {
$chunkIds[] = $chunkId;
}
}
}
return $chunkIds;
}
}
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 2070 |
6 |
modified |
7.4 KB |
2025-12-28 23:32 |
| 2069 |
5 |
modified |
7.3 KB |
2025-12-28 23:32 |
| 2068 |
4 |
modified |
7.2 KB |
2025-12-28 23:32 |
| 1521 |
3 |
modified |
7.2 KB |
2025-12-25 20:19 |
| 1520 |
2 |
modified |
7.2 KB |
2025-12-25 20:19 |
| 1518 |
1 |
modified |
7.3 KB |
2025-12-25 20:17 |
← Zurück zur Übersicht