Backup #1606
| ID | 1606 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/Infrastructure/Persistence/SemanticSearchRepository.php |
| Version | 6 |
| Typ |
modified |
| Größe | 5.6 KB |
| Hash | 8e42855a4575f1eed56873b8cb39d62297995d8a9284dbada63007afb20347e2 |
| Datum | 2025-12-27 00:27:38 |
| 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 Infrastructure\Persistence;
// @responsibility: Semantik-Suche und Graph-Daten für Semantic Explorer
use Domain\Repository\SemanticSearchRepositoryInterface;
use PDO;
final class SemanticSearchRepository implements SemanticSearchRepositoryInterface
{
private PDO $db;
public function __construct(PDO $pdo)
{
$this->db = $pdo;
}
/**
* {@inheritDoc}
*/
public function getSemanticStats(): array
{
return $this->db->query(
'SELECT
(SELECT COUNT(*) FROM entities) as entities,
(SELECT COUNT(*) FROM entity_relations) as relations,
(SELECT COUNT(*) FROM taxonomy_terms) as taxonomy,
(SELECT COUNT(*) FROM ontology_classes) as ontology,
(SELECT COUNT(*) FROM chunk_semantics) as semantics,
(SELECT COUNT(*) FROM entities) as total,
(SELECT COUNT(DISTINCT type) FROM entities) as types,
(SELECT COUNT(DISTINCT chunk_id) FROM chunk_entities) as linked_chunks,
(SELECT COUNT(DISTINCT c.document_id) FROM chunk_entities ce JOIN chunks c ON ce.chunk_id = c.id) as linked_docs'
)->fetch();
}
/**
* {@inheritDoc}
*/
public function findEntitySemantics(string $search = '', string $type = '', int $limit = 50, int $offset = 0): array
{
// Deduplicated entities with aggregated chunk/document counts
$sql = 'SELECT e.id, e.name, e.canonical_name, e.type, e.description, e.status,
COUNT(DISTINCT ce.chunk_id) as chunk_count,
COUNT(DISTINCT c.document_id) as document_count,
MIN(ce.chunk_id) as first_chunk_id,
MIN(d.filename) as first_filename,
MIN(d.id) as first_document_id
FROM entities e
LEFT JOIN chunk_entities ce ON e.id = ce.entity_id
LEFT JOIN chunks c ON ce.chunk_id = c.id
LEFT JOIN documents d ON c.document_id = d.id
WHERE 1=1';
$params = [];
if ($search !== '') {
$sql .= ' AND (e.name LIKE :search OR e.description LIKE :search2 OR e.canonical_name LIKE :search3)';
$params['search'] = '%' . $search . '%';
$params['search2'] = '%' . $search . '%';
$params['search3'] = '%' . $search . '%';
}
if ($type !== '') {
$sql .= ' AND e.type = :type';
$params['type'] = $type;
}
$sql .= ' GROUP BY e.id, e.name, e.canonical_name, e.type, e.description, e.status';
$sql .= ' ORDER BY e.name LIMIT ' . $limit . ' OFFSET ' . $offset;
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
/**
* {@inheritDoc}
*/
public function countEntitySemantics(string $search = '', string $type = ''): int
{
$sql = 'SELECT COUNT(DISTINCT e.id) FROM entities e WHERE 1=1';
$params = [];
if ($search !== '') {
$sql .= ' AND (e.name LIKE :search OR e.description LIKE :search2 OR e.canonical_name LIKE :search3)';
$params['search'] = '%' . $search . '%';
$params['search2'] = '%' . $search . '%';
$params['search3'] = '%' . $search . '%';
}
if ($type !== '') {
$sql .= ' AND e.type = :type';
$params['type'] = $type;
}
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return (int) $stmt->fetchColumn();
}
/**
* {@inheritDoc}
*/
public function getGraphData(): array
{
// Get all entities
$entities = $this->db->query(
'SELECT id, name, type FROM entities ORDER BY name'
)->fetchAll();
// Get all relations
$relations = $this->db->query(
'SELECT source_entity_id, target_entity_id, relation_type, strength
FROM entity_relations'
)->fetchAll();
// Build node index for link resolution
$nodeIndex = [];
$nodes = [];
foreach ($entities as $i => $entity) {
$nodeIndex[$entity['id']] = $i;
$nodes[] = [
'id' => 'entity_' . $entity['id'],
'label' => $entity['name'],
'type' => strtoupper($entity['type'] ?? 'OTHER'),
'entityId' => (int) $entity['id'],
];
}
// Build links with index references
$links = [];
foreach ($relations as $relation) {
$sourceId = $relation['source_entity_id'];
$targetId = $relation['target_entity_id'];
// Skip if entity not found
if (!isset($nodeIndex[$sourceId]) || !isset($nodeIndex[$targetId])) {
continue;
}
$links[] = [
'source' => $nodeIndex[$sourceId],
'target' => $nodeIndex[$targetId],
'type' => $relation['relation_type'],
'strength' => (float) ($relation['strength'] ?? 1.0),
];
}
// Get unique types for stats
$entityTypes = array_unique(array_column($nodes, 'type'));
$relationTypes = array_unique(array_column($links, 'type'));
return [
'nodes' => $nodes,
'links' => $links,
'stats' => [
'nodes' => count($nodes),
'links' => count($links),
'entityTypes' => count($entityTypes),
'relationTypes' => count($relationTypes),
],
];
}
}
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 2195 |
13 |
modified |
8.3 KB |
2025-12-31 02:23 |
| 2194 |
12 |
modified |
8.3 KB |
2025-12-31 02:22 |
| 2193 |
11 |
modified |
8.3 KB |
2025-12-31 02:22 |
| 2190 |
10 |
modified |
8.3 KB |
2025-12-31 02:21 |
| 2189 |
9 |
modified |
8.3 KB |
2025-12-31 02:20 |
| 2188 |
8 |
modified |
8.3 KB |
2025-12-31 02:19 |
| 1990 |
7 |
modified |
5.7 KB |
2025-12-28 03:04 |
| 1606 |
6 |
modified |
5.6 KB |
2025-12-27 00:27 |
| 1534 |
5 |
modified |
5.3 KB |
2025-12-26 14:51 |
| 1524 |
4 |
modified |
5.2 KB |
2025-12-26 06:52 |
| 1523 |
3 |
modified |
4.7 KB |
2025-12-26 06:51 |
| 1170 |
2 |
modified |
4.7 KB |
2025-12-25 10:28 |
| 1163 |
1 |
modified |
4.8 KB |
2025-12-25 10:28 |
← Zurück zur Übersicht