rm CachedRetriever.php
add second shopsearch
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user