rm CachedRetriever.php

add second shopsearch
This commit is contained in:
team 1
2026-04-19 14:20:23 +02:00
parent a71426c300
commit 4d944a5113
9 changed files with 1075 additions and 129 deletions

View File

@@ -207,10 +207,12 @@ final readonly class ShopSearchService
);
}
return array_values(array_filter(
$results = array_values(array_filter(
$results,
static fn(ShopProductResult $product): bool => $product->name !== ''
));
return $this->deduplicateProducts($results);
}
/**
@@ -251,26 +253,46 @@ final readonly class ShopSearchService
{
$score = 0;
$normalizedPrompt = $this->normalizeForMatching($query->normalizedPrompt ?: $query->originalPrompt);
$normalizedPrompt = $this->normalizeForMatching($query->normalizedPrompt !== ''
? $query->normalizedPrompt
: $query->originalPrompt);
$normalizedSearchText = $this->normalizeForMatching($query->searchText);
$normalizedQuery = trim($normalizedPrompt . ' ' . $normalizedSearchText);
$normalizedBrand = $this->normalizeForMatching((string) ($query->brand ?? ''));
$normalizedSizes = array_values(array_filter(array_map(
fn(mixed $size): string => $this->normalizeForMatching((string) $size),
$query->sizes
)));
$normalizedQuery = trim(implode(' ', array_filter([
$normalizedPrompt,
$normalizedSearchText,
$normalizedBrand,
implode(' ', $normalizedSizes),
])));
$queryTokens = $this->tokenize($normalizedQuery);
$queryNumberTokens = $this->extractNumberTokens($queryTokens);
$normalizedProductName = $this->normalizeForMatching($product->name);
$productNameTokens = $this->tokenize($normalizedProductName);
$productNameNumberTokens = $this->extractNumberTokens($productNameTokens);
$normalizedProductNumber = $this->normalizeForMatching((string) ($product->productNumber ?? ''));
$productNumberTokens = $this->tokenize($normalizedProductNumber);
$productNumberNumberTokens = $this->extractNumberTokens($productNumberTokens);
$normalizedManufacturer = $this->normalizeForMatching((string) ($product->manufacturer ?? ''));
$normalizedBrand = $this->normalizeForMatching((string) ($query->brand ?? ''));
$normalizedProductCorpus = $this->buildNormalizedProductCorpus($product);
$productNameTokens = $this->tokenize($normalizedProductName);
$productNumberTokens = $this->tokenize($normalizedProductNumber);
$productCorpusTokens = $this->tokenize($normalizedProductCorpus);
$productNameNumberTokens = $this->extractNumberTokens($productNameTokens);
$productNumberNumberTokens = $this->extractNumberTokens($productNumberTokens);
$productCorpusNumberTokens = $this->extractNumberTokens($productCorpusTokens);
if ($normalizedProductNumber !== '' && $this->containsWholePhrase($normalizedQuery, $normalizedProductNumber)) {
$score += 120;
$score += 140;
}
if ($normalizedProductName !== '' && $this->containsWholePhrase($normalizedQuery, $normalizedProductName)) {
$score += 80;
}
if ($normalizedBrand !== '') {
@@ -281,20 +303,22 @@ final readonly class ShopSearchService
}
}
$score += $this->countOverlap($queryTokens, $productNameTokens) * 4;
$score += $this->countOverlap($queryTokens, $productNumberTokens) * 8;
$score += $this->countOverlap($queryNumberTokens, $productNameNumberTokens) * 16;
$score += $this->countOverlap($queryNumberTokens, $productNumberNumberTokens) * 24;
$score += $this->countOverlap($queryTokens, $productNameTokens) * 6;
$score += $this->countOverlap($queryTokens, $productNumberTokens) * 10;
$score += $this->countOverlap($queryTokens, $productCorpusTokens) * 2;
foreach ($query->sizes as $size) {
$normalizedSize = $this->normalizeForMatching((string) $size);
$score += $this->countOverlap($queryNumberTokens, $productNameNumberTokens) * 18;
$score += $this->countOverlap($queryNumberTokens, $productNumberNumberTokens) * 28;
$score += $this->countOverlap($queryNumberTokens, $productCorpusNumberTokens) * 8;
foreach ($normalizedSizes as $normalizedSize) {
if ($normalizedSize === '') {
continue;
}
if ($this->containsWholePhrase($normalizedProductName, $normalizedSize)
|| $this->containsWholePhrase($normalizedProductNumber, $normalizedSize)) {
|| $this->containsWholePhrase($normalizedProductNumber, $normalizedSize)
|| $this->containsWholePhrase($normalizedProductCorpus, $normalizedSize)) {
$score += 12;
}
}
@@ -306,6 +330,18 @@ final readonly class ShopSearchService
return $score;
}
private function buildNormalizedProductCorpus(ShopProductResult $product): string
{
return $this->normalizeForMatching(implode(' ', array_filter([
$product->name,
$product->productNumber,
$product->manufacturer,
implode(' ', $product->highlights),
$product->description,
$product->customFields,
])));
}
/**
* @param string[] $left
* @param string[] $right
@@ -480,4 +516,32 @@ final readonly class ShopSearchService
return array_values(array_unique($highlights));
}
/**
* @param ShopProductResult[] $products
* @return ShopProductResult[]
*/
private function deduplicateProducts(array $products): array
{
$unique = [];
$seen = [];
foreach ($products as $product) {
$key = mb_strtolower(trim(implode('|', [
$product->id,
$product->productNumber ?? '',
$product->name,
$product->url ?? '',
])));
if (isset($seen[$key])) {
continue;
}
$seen[$key] = true;
$unique[] = $product;
}
return $unique;
}
}