You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
5.6 KiB
PowerShell
165 lines
5.6 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Semantische Suche in TED Ausschreibungen
|
|
.DESCRIPTION
|
|
Fuehrt eine semantische Aehnlichkeitssuche gegen die TED Procurement Datenbank durch.
|
|
.PARAMETER Query
|
|
Der Suchtext fuer die semantische Suche
|
|
.PARAMETER TopK
|
|
Anzahl der zurueckgegebenen Ergebnisse (Standard: 10, Max: 100)
|
|
.PARAMETER Threshold
|
|
Minimaler Aehnlichkeitsschwellwert 0.0-1.0 (Standard: 0.5)
|
|
.PARAMETER ApiUrl
|
|
URL des API-Servers (Standard: http://localhost:8888/api)
|
|
.EXAMPLE
|
|
.\Search-TED.ps1 -Query "Software Entwicklung Cloud Services"
|
|
.EXAMPLE
|
|
.\Search-TED.ps1 -Query "IT Beratung Digitalisierung" -TopK 20 -Threshold 0.6
|
|
#>
|
|
|
|
param(
|
|
[Parameter(Mandatory=$true, Position=0, HelpMessage="Suchtext fuer semantische Suche")]
|
|
[string]$Query,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateRange(1, 100)]
|
|
[int]$TopK = 100,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateRange(0.0, 1.0)]
|
|
[double]$Threshold = 0.5,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$ApiUrl = "http://localhost:8888/api"
|
|
)
|
|
|
|
# Farben fuer Ausgabe
|
|
$colors = @{
|
|
Header = "Cyan"
|
|
Success = "Green"
|
|
Warning = "Yellow"
|
|
Error = "Red"
|
|
Info = "White"
|
|
Highlight = "Magenta"
|
|
}
|
|
|
|
function Write-Header {
|
|
param([string]$Text)
|
|
Write-Host ""
|
|
Write-Host ("=" * 80) -ForegroundColor $colors.Header
|
|
Write-Host $Text -ForegroundColor $colors.Header
|
|
Write-Host ("=" * 80) -ForegroundColor $colors.Header
|
|
}
|
|
|
|
function Write-Result {
|
|
param(
|
|
[int]$Rank,
|
|
[PSObject]$Doc
|
|
)
|
|
|
|
$similarity = if ($Doc.similarityPercent) { "$($Doc.similarityPercent)%" } else { "N/A" }
|
|
$deadline = "-"
|
|
if ($Doc.submissionDeadline) {
|
|
try {
|
|
# Handle ISO 8601 format (e.g., "2025-04-28T06:00:59Z")
|
|
$deadline = ([DateTime]::Parse($Doc.submissionDeadline, [System.Globalization.CultureInfo]::InvariantCulture)).ToString("dd.MM.yyyy")
|
|
} catch {
|
|
$deadline = $Doc.submissionDeadline.Substring(0, 10) # Fallback: first 10 chars (YYYY-MM-DD)
|
|
}
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "[$Rank] " -NoNewline -ForegroundColor $colors.Highlight
|
|
Write-Host "$similarity Aehnlichkeit" -ForegroundColor $colors.Success
|
|
Write-Host " Titel: " -NoNewline -ForegroundColor $colors.Info
|
|
Write-Host $Doc.projectTitle -ForegroundColor $colors.Warning
|
|
Write-Host " Auftraggeber: " -NoNewline -ForegroundColor $colors.Info
|
|
Write-Host "$($Doc.buyerName) ($($Doc.buyerCountryCode))" -ForegroundColor White
|
|
Write-Host " Vertragsart: " -NoNewline -ForegroundColor $colors.Info
|
|
Write-Host $Doc.contractNature -ForegroundColor White
|
|
Write-Host " Einreichfrist:" -NoNewline -ForegroundColor $colors.Info
|
|
Write-Host " $deadline" -ForegroundColor White
|
|
Write-Host " TED Link: " -NoNewline -ForegroundColor $colors.Info
|
|
Write-Host $Doc.noticeUrl -ForegroundColor Cyan
|
|
|
|
if ($Doc.projectDescription) {
|
|
$desc = $Doc.projectDescription
|
|
if ($desc.Length -gt 200) {
|
|
$desc = $desc.Substring(0, 197) + "..."
|
|
}
|
|
Write-Host " Beschreibung: " -NoNewline -ForegroundColor $colors.Info
|
|
Write-Host $desc -ForegroundColor DarkGray
|
|
}
|
|
}
|
|
|
|
# Hauptprogramm
|
|
try {
|
|
Write-Header "TED Semantische Suche"
|
|
Write-Host "Suchtext: " -NoNewline -ForegroundColor $colors.Info
|
|
Write-Host $Query -ForegroundColor $colors.Warning
|
|
Write-Host "Parameter: TopK=$TopK, Threshold=$Threshold" -ForegroundColor DarkGray
|
|
Write-Host ""
|
|
|
|
# Request Body erstellen
|
|
$body = @{
|
|
text = $Query
|
|
topK = $TopK
|
|
threshold = $Threshold
|
|
} | ConvertTo-Json
|
|
|
|
# API aufrufen
|
|
Write-Host "Suche laeuft..." -ForegroundColor $colors.Info
|
|
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
|
|
|
$response = Invoke-RestMethod -Uri "$ApiUrl/similarity/text" `
|
|
-Method Post `
|
|
-ContentType "application/json; charset=utf-8" `
|
|
-Body $body `
|
|
-ErrorAction Stop
|
|
|
|
$stopwatch.Stop()
|
|
|
|
# Ergebnisse anzeigen
|
|
$resultCount = $response.resultCount
|
|
$embeddingTime = $response.embeddingTimeMs
|
|
$searchTime = $response.searchTimeMs
|
|
$totalTime = $stopwatch.ElapsedMilliseconds
|
|
|
|
Write-Header "Suchergebnisse: $resultCount Treffer"
|
|
Write-Host "Zeiten: Embedding=${embeddingTime}ms, Suche=${searchTime}ms, Gesamt=${totalTime}ms" -ForegroundColor DarkGray
|
|
|
|
if ($resultCount -eq 0) {
|
|
Write-Host ""
|
|
Write-Host "Keine passenden Ausschreibungen gefunden." -ForegroundColor $colors.Warning
|
|
Write-Host "Versuchen Sie:" -ForegroundColor $colors.Info
|
|
Write-Host " - Andere Suchbegriffe" -ForegroundColor DarkGray
|
|
Write-Host " - Niedrigeren Schwellwert (-Threshold 0.3)" -ForegroundColor DarkGray
|
|
}
|
|
else {
|
|
$rank = 1
|
|
foreach ($doc in $response.results) {
|
|
Write-Result -Rank $rank -Doc $doc
|
|
$rank++
|
|
}
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host ("-" * 80) -ForegroundColor DarkGray
|
|
Write-Host "Suche abgeschlossen." -ForegroundColor $colors.Success
|
|
|
|
} catch {
|
|
Write-Host ""
|
|
Write-Host "FEHLER: $_" -ForegroundColor $colors.Error
|
|
|
|
if ($_.Exception.Response.StatusCode -eq 503) {
|
|
Write-Host "Der Vektorisierungsdienst ist nicht verfuegbar." -ForegroundColor $colors.Warning
|
|
Write-Host "Stellen Sie sicher, dass der Embedding-Service auf Port 8001 laeuft." -ForegroundColor $colors.Info
|
|
}
|
|
elseif ($_.Exception.Message -like "*Unable to connect*") {
|
|
Write-Host "Konnte keine Verbindung zum Server herstellen." -ForegroundColor $colors.Warning
|
|
Write-Host "Stellen Sie sicher, dass die Anwendung auf $ApiUrl laeuft." -ForegroundColor $colors.Info
|
|
}
|
|
|
|
exit 1
|
|
}
|