central config part 2
This commit is contained in:
@@ -6,82 +6,165 @@ namespace App\Config;
|
||||
|
||||
final class CommerceIntentConfig
|
||||
{
|
||||
private const STRONG_SIGNALS = [
|
||||
'shop',
|
||||
'alle',
|
||||
'preis',
|
||||
'kunde',
|
||||
'online',
|
||||
'produkt',
|
||||
'artikel',
|
||||
'sku',
|
||||
'kaufen',
|
||||
'kostet',
|
||||
'suche',
|
||||
'such',
|
||||
'finde',
|
||||
'finden',
|
||||
'analysegerät',
|
||||
'analysegeraet',
|
||||
'messgerät',
|
||||
'messgeraet',
|
||||
'analysator',
|
||||
'analyzer',
|
||||
'puffer',
|
||||
'kalibrierpuffer',
|
||||
'kalibrierlösung',
|
||||
'kalibrierloesung',
|
||||
'kalibrierung',
|
||||
'chemie',
|
||||
'reagenz',
|
||||
'reagenzien',
|
||||
'verbrauchsmaterial',
|
||||
'zubehör',
|
||||
'zubehoer',
|
||||
'ersatzteil',
|
||||
];
|
||||
|
||||
private const ADVISORY_SIGNALS = [
|
||||
'passt',
|
||||
'eignet',
|
||||
'besser',
|
||||
'besten',
|
||||
'gut für',
|
||||
'gut fuer',
|
||||
'passend für',
|
||||
'passend fuer',
|
||||
'geeignet',
|
||||
'geeigent',
|
||||
'empfiehl',
|
||||
'empfehl',
|
||||
];
|
||||
|
||||
private const PRICE_TERMS = [
|
||||
'euro',
|
||||
'€',
|
||||
'eur',
|
||||
'teuer',
|
||||
'preis',
|
||||
'kosten',
|
||||
'kostet',
|
||||
];
|
||||
|
||||
private const COLOR_TERMS = [
|
||||
'schwarz',
|
||||
'weiß',
|
||||
'weis',
|
||||
'blau',
|
||||
'grau',
|
||||
'beige',
|
||||
'rosa',
|
||||
'pink',
|
||||
'gruen',
|
||||
'orange',
|
||||
'braun',
|
||||
];
|
||||
|
||||
private const SIZE_TOKEN_TERMS = [
|
||||
'xs',
|
||||
's',
|
||||
'm',
|
||||
'l',
|
||||
'xl',
|
||||
'xxl',
|
||||
'xxxxl',
|
||||
];
|
||||
|
||||
private const SIZE_TERMS = [
|
||||
'größe',
|
||||
'groesse',
|
||||
'grösse',
|
||||
];
|
||||
|
||||
private const SUPPORT_DIAGNOSTIC_PATTERNS = [
|
||||
'/\bfehler\b/u',
|
||||
'/\bfehlercode\b/u',
|
||||
'/\berror\b/u',
|
||||
'/\bstörung\b/u',
|
||||
'/\bstoerung\b/u',
|
||||
'/\balarm\b/u',
|
||||
'/\bstörungsmeldung\b/u',
|
||||
'/\bstoerungsmeldung\b/u',
|
||||
'/\bmeldung\b/u',
|
||||
'/\bwarnung\b/u',
|
||||
'/\bwarncode\b/u',
|
||||
'/\bcode\b/u',
|
||||
'/\bwas bedeutet\b/u',
|
||||
'/\bwarum\b/u',
|
||||
'/\bblinkt\b/u',
|
||||
'/\bzeigt\b/u',
|
||||
'/\bzeigt an\b/u',
|
||||
'/\bursache\b/u',
|
||||
'/\bdiagnose\b/u',
|
||||
'/\bservicefall\b/u',
|
||||
'/\bproblem\b/u',
|
||||
'/\bstörung beheben\b/u',
|
||||
'/\bstoerung beheben\b/u',
|
||||
'/\be\d{1,3}\b/u',
|
||||
];
|
||||
|
||||
private const EXPLICIT_COMMERCE_INTENT_PATTERNS = [
|
||||
'/\bshop\b/u',
|
||||
'/\bpreis\b/u',
|
||||
'/\bkosten\b/u',
|
||||
'/\bkostet\b/u',
|
||||
'/\bkaufen\b/u',
|
||||
'/\bbestellen\b/u',
|
||||
'/\bprodukt\b/u',
|
||||
'/\bartikel\b/u',
|
||||
'/\bsku\b/u',
|
||||
'/\bonline\b/u',
|
||||
'/\bchemie\b/u',
|
||||
'/\breagenz(?:ien)?\b/u',
|
||||
'/\bverbrauchsmaterial(?:ien)?\b/u',
|
||||
'/\bzubehör\b/u',
|
||||
'/\bzubehoer\b/u',
|
||||
'/\bersatzteil(?:e)?\b/u',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
public function __construct(private readonly array $config = [])
|
||||
{
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getStrongSignalsList(): array
|
||||
{
|
||||
return [
|
||||
'shop',
|
||||
'alle',
|
||||
'preis',
|
||||
'kunde',
|
||||
'online',
|
||||
'produkt',
|
||||
'artikel',
|
||||
'sku',
|
||||
'kaufen',
|
||||
'kostet',
|
||||
'suche',
|
||||
'such',
|
||||
'finde',
|
||||
'finden',
|
||||
'analysegerät',
|
||||
'analysegeraet',
|
||||
'messgerät',
|
||||
'messgeraet',
|
||||
'analysator',
|
||||
'analyzer',
|
||||
'puffer',
|
||||
'kalibrierpuffer',
|
||||
'kalibrierlösung',
|
||||
'kalibrierloesung',
|
||||
'kalibrierung',
|
||||
'chemie',
|
||||
'reagenz',
|
||||
'reagenzien',
|
||||
'verbrauchsmaterial',
|
||||
'zubehör',
|
||||
'zubehoer',
|
||||
'ersatzteil',
|
||||
];
|
||||
return $this->stringList('strong_signals', self::STRONG_SIGNALS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getAdvisorySignals(): array
|
||||
{
|
||||
return [
|
||||
'passt',
|
||||
'eignet',
|
||||
'besser',
|
||||
'besten',
|
||||
'gut für',
|
||||
'gut fuer',
|
||||
'passend für',
|
||||
'passend fuer',
|
||||
'geeignet',
|
||||
'geeigent',
|
||||
'empfiehl',
|
||||
'empfehl',
|
||||
];
|
||||
return $this->stringList('advisory_signals', self::ADVISORY_SIGNALS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getPriceTerms(): array
|
||||
{
|
||||
return [
|
||||
'euro',
|
||||
'€',
|
||||
'eur',
|
||||
'teuer',
|
||||
'preis',
|
||||
'kosten',
|
||||
'kostet',
|
||||
];
|
||||
return $this->stringList('price_terms', self::PRICE_TERMS);
|
||||
}
|
||||
|
||||
public function getPricePattern(): string
|
||||
@@ -89,24 +172,10 @@ final class CommerceIntentConfig
|
||||
return implode('|', $this->getPriceTerms());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getColorTerms(): array
|
||||
{
|
||||
return [
|
||||
'schwarz',
|
||||
'weiß',
|
||||
'weis',
|
||||
'blau',
|
||||
'grau',
|
||||
'beige',
|
||||
'rosa',
|
||||
'pink',
|
||||
'gruen',
|
||||
'orange',
|
||||
'braun',
|
||||
];
|
||||
return $this->stringList('color_terms', self::COLOR_TERMS);
|
||||
}
|
||||
|
||||
public function getColorPattern(): string
|
||||
@@ -114,20 +183,10 @@ final class CommerceIntentConfig
|
||||
return implode('|', $this->getColorTerms());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getSizeTokenTerms(): array
|
||||
{
|
||||
return [
|
||||
'xs',
|
||||
's',
|
||||
'm',
|
||||
'l',
|
||||
'xl',
|
||||
'xxl',
|
||||
'xxxxl',
|
||||
];
|
||||
return $this->stringList('size_token_terms', self::SIZE_TOKEN_TERMS);
|
||||
}
|
||||
|
||||
public function getSizeTokenPattern(): string
|
||||
@@ -135,16 +194,10 @@ final class CommerceIntentConfig
|
||||
return implode('|', $this->getSizeTokenTerms());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getSizeTerms(): array
|
||||
{
|
||||
return [
|
||||
'größe',
|
||||
'groesse',
|
||||
'grösse',
|
||||
];
|
||||
return $this->stringList('size_terms', self::SIZE_TERMS);
|
||||
}
|
||||
|
||||
public function getSizePattern(): string
|
||||
@@ -157,62 +210,16 @@ final class CommerceIntentConfig
|
||||
return '/\b(?:' . $this->getSizePattern() . ')\s*([a-z0-9.-]+)\b/u';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getSupportDiagnosticPatterns(): array
|
||||
{
|
||||
return [
|
||||
'/\bfehler\b/u',
|
||||
'/\bfehlercode\b/u',
|
||||
'/\berror\b/u',
|
||||
'/\bstörung\b/u',
|
||||
'/\bstoerung\b/u',
|
||||
'/\balarm\b/u',
|
||||
'/\bstörungsmeldung\b/u',
|
||||
'/\bstoerungsmeldung\b/u',
|
||||
'/\bmeldung\b/u',
|
||||
'/\bwarnung\b/u',
|
||||
'/\bwarncode\b/u',
|
||||
'/\bcode\b/u',
|
||||
'/\bwas bedeutet\b/u',
|
||||
'/\bwarum\b/u',
|
||||
'/\bblinkt\b/u',
|
||||
'/\bzeigt\b/u',
|
||||
'/\bzeigt an\b/u',
|
||||
'/\bursache\b/u',
|
||||
'/\bdiagnose\b/u',
|
||||
'/\bservicefall\b/u',
|
||||
'/\bproblem\b/u',
|
||||
'/\bstörung beheben\b/u',
|
||||
'/\bstoerung beheben\b/u',
|
||||
'/\be\d{1,3}\b/u',
|
||||
];
|
||||
return $this->stringList('support_diagnostic_patterns', self::SUPPORT_DIAGNOSTIC_PATTERNS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getExplicitCommerceIntentPatterns(): array
|
||||
{
|
||||
return [
|
||||
'/\bshop\b/u',
|
||||
'/\bpreis\b/u',
|
||||
'/\bkosten\b/u',
|
||||
'/\bkostet\b/u',
|
||||
'/\bkaufen\b/u',
|
||||
'/\bbestellen\b/u',
|
||||
'/\bprodukt\b/u',
|
||||
'/\bartikel\b/u',
|
||||
'/\bsku\b/u',
|
||||
'/\bonline\b/u',
|
||||
'/\bchemie\b/u',
|
||||
'/\breagenz(?:ien)?\b/u',
|
||||
'/\bverbrauchsmaterial(?:ien)?\b/u',
|
||||
'/\bzubehör\b/u',
|
||||
'/\bzubehoer\b/u',
|
||||
'/\bersatzteil(?:e)?\b/u',
|
||||
];
|
||||
return $this->stringList('explicit_commerce_intent_patterns', self::EXPLICIT_COMMERCE_INTENT_PATTERNS);
|
||||
}
|
||||
|
||||
public function getSkuLikePattern(): string
|
||||
@@ -334,4 +341,29 @@ final class CommerceIntentConfig
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
private function stringList(string $key, array $default): array
|
||||
{
|
||||
$value = $this->config[$key] ?? $default;
|
||||
if (!is_array($value)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($value as $item) {
|
||||
if (!is_scalar($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = trim((string) $item);
|
||||
if ($item === '' || in_array($item, $out, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$out[] = $item;
|
||||
}
|
||||
|
||||
return $out !== [] ? $out : $default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Config;
|
||||
|
||||
class IntentLightConfig
|
||||
{
|
||||
public const LIST_THRESHOLD = 4;
|
||||
|
||||
public function getQuantityWords(): array
|
||||
private const QUANTITY_WORDS = [
|
||||
'alle',
|
||||
'sämtliche',
|
||||
'saemtliche',
|
||||
'mehrere',
|
||||
'verschiedene',
|
||||
'einige',
|
||||
'viele',
|
||||
'optionen',
|
||||
'möglichkeiten',
|
||||
'moeglichkeiten',
|
||||
'varianten',
|
||||
'arten',
|
||||
'modelle',
|
||||
'funktionen',
|
||||
'punkte',
|
||||
'schritte',
|
||||
'kategorien',
|
||||
'übersicht',
|
||||
'uebersicht',
|
||||
];
|
||||
|
||||
private const STRONG_PATTERNS = [
|
||||
'/\bliste(n)?\b/u',
|
||||
'/\bauflisten\b/u',
|
||||
'/\baufz(a|ä)hl(en)?\b/u',
|
||||
'/\bnenn(e)?\b/u',
|
||||
'/\bzeig(e)?\b/u',
|
||||
'/\bwelche\s+sind\b/u',
|
||||
'/\bwelche\s+gibt\s+es\b/u',
|
||||
'/\bwas\s+sind\b/u',
|
||||
'/\bwie\s+viele\b/u',
|
||||
'/\branking\b/u',
|
||||
'/\btop\s*\d+\b/u',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
public function __construct(private readonly array $config = [])
|
||||
{
|
||||
return [
|
||||
'alle',
|
||||
'sämtliche',
|
||||
'saemtliche',
|
||||
'mehrere',
|
||||
'verschiedene',
|
||||
'einige',
|
||||
'viele',
|
||||
'optionen',
|
||||
'möglichkeiten',
|
||||
'moeglichkeiten',
|
||||
'varianten',
|
||||
'arten',
|
||||
'modelle',
|
||||
'funktionen',
|
||||
'punkte',
|
||||
'schritte',
|
||||
'kategorien',
|
||||
'übersicht',
|
||||
'uebersicht',
|
||||
];
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getQuantityWords(): array
|
||||
{
|
||||
return $this->stringList('quantity_words', self::QUANTITY_WORDS);
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getStrongPatterns(): array
|
||||
{
|
||||
return [
|
||||
'/\bliste(n)?\b/u',
|
||||
'/\bauflisten\b/u',
|
||||
'/\baufz(a|ä)hl(en)?\b/u',
|
||||
'/\bnenn(e)?\b/u',
|
||||
'/\bzeig(e)?\b/u',
|
||||
'/\bwelche\s+sind\b/u',
|
||||
'/\bwelche\s+gibt\s+es\b/u',
|
||||
'/\bwas\s+sind\b/u',
|
||||
'/\bwie\s+viele\b/u',
|
||||
'/\branking\b/u',
|
||||
'/\btop\s*\d+\b/u',
|
||||
];
|
||||
return $this->stringList('strong_patterns', self::STRONG_PATTERNS);
|
||||
}
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
private function stringList(string $key, array $default): array
|
||||
{
|
||||
$value = $this->config[$key] ?? $default;
|
||||
if (!is_array($value)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($value as $item) {
|
||||
if (!is_scalar($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = trim((string) $item);
|
||||
if ($item === '' || in_array($item, $out, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$out[] = $item;
|
||||
}
|
||||
|
||||
return $out !== [] ? $out : $default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +1,142 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Config;
|
||||
|
||||
class SalesIntentConfig
|
||||
{
|
||||
|
||||
// Minimum gap between Top 1 and Top 2 so that an intent is truly dominant.
|
||||
public const DOMINANCE_DELTA = 2;
|
||||
|
||||
// Minimum score required for any non-discovery intent to be accepted.
|
||||
public const MIN_SCORE_THRESHOLD = 3;
|
||||
|
||||
private const SALES_SIGNALS = [
|
||||
'preis',
|
||||
'preise',
|
||||
'kosten',
|
||||
'lizenz',
|
||||
'lizenzmodell',
|
||||
'tarif',
|
||||
'tarife',
|
||||
'gebuehr',
|
||||
'gebühr',
|
||||
'monatlich',
|
||||
'jaehrlich',
|
||||
'jährlich',
|
||||
'abo',
|
||||
'subscription',
|
||||
];
|
||||
|
||||
private const COMPARISON_SIGNALS = [
|
||||
'/\bvergleich(en)?\b/u',
|
||||
'/\bvs\b/u',
|
||||
'/\bgegenueber\b/u',
|
||||
'/\balternative(n)?\b/u',
|
||||
'/\bunterschied(e)?\b/u',
|
||||
'/\bbesser\b/u',
|
||||
];
|
||||
|
||||
private const OBJECTION_SIGNALS = [
|
||||
'problem',
|
||||
'risiko',
|
||||
'nachteil',
|
||||
'datenschutz',
|
||||
'dsgvo',
|
||||
'sicherheit',
|
||||
'compliance',
|
||||
'kritik',
|
||||
'zweifel',
|
||||
'unsicher',
|
||||
];
|
||||
|
||||
private const IMPLEMENTATION_SIGNALS = [
|
||||
'implementierung',
|
||||
'implementieren',
|
||||
'integration',
|
||||
'integrieren',
|
||||
'einführung',
|
||||
'einfuehrung',
|
||||
'aufwand',
|
||||
'setup',
|
||||
'rollout',
|
||||
'migration',
|
||||
'installation',
|
||||
'api',
|
||||
'schnittstelle',
|
||||
];
|
||||
|
||||
private const ROI_SIGNALS = [
|
||||
'roi',
|
||||
'rentabilitaet',
|
||||
'rentabilität',
|
||||
'business case',
|
||||
'einsparung',
|
||||
'kosten senken',
|
||||
'umsatz steigern',
|
||||
'effizienz steigern',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
public function __construct(private readonly array $config = [])
|
||||
{
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getSalesSignals(): array
|
||||
{
|
||||
return [
|
||||
'preis', 'preise', 'kosten', 'lizenz', 'lizenzmodell',
|
||||
'tarif', 'tarife', 'gebuehr', 'gebühr',
|
||||
'monatlich', 'jaehrlich', 'jährlich', 'abo', 'subscription'
|
||||
];
|
||||
return $this->stringList('sales_signals', self::SALES_SIGNALS);
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getComparisonSignals(): array
|
||||
{
|
||||
return [
|
||||
'/\bvergleich(en)?\b/u',
|
||||
'/\bvs\b/u',
|
||||
'/\bgegenueber\b/u',
|
||||
'/\balternative(n)?\b/u',
|
||||
'/\bunterschied(e)?\b/u',
|
||||
'/\bbesser\b/u'
|
||||
];
|
||||
return $this->stringList('comparison_signals', self::COMPARISON_SIGNALS);
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getObjectionSignals(): array
|
||||
{
|
||||
return [
|
||||
'problem', 'risiko', 'nachteil', 'datenschutz',
|
||||
'dsgvo', 'sicherheit', 'compliance',
|
||||
'kritik', 'zweifel', 'unsicher'
|
||||
];
|
||||
}
|
||||
public function getImplementationSignals(): array
|
||||
{
|
||||
return [
|
||||
'implementierung', 'implementieren',
|
||||
'integration', 'integrieren',
|
||||
'einführung', 'einfuehrung',
|
||||
'aufwand', 'setup', 'rollout',
|
||||
'migration', 'installation',
|
||||
'api', 'schnittstelle'
|
||||
];
|
||||
}
|
||||
public function getRoiSignals(): array
|
||||
{
|
||||
return [
|
||||
'roi', 'rentabilitaet', 'rentabilität',
|
||||
'business case', 'einsparung',
|
||||
'kosten senken', 'umsatz steigern',
|
||||
'effizienz steigern'
|
||||
];
|
||||
return $this->stringList('objection_signals', self::OBJECTION_SIGNALS);
|
||||
}
|
||||
|
||||
}
|
||||
/** @return string[] */
|
||||
public function getImplementationSignals(): array
|
||||
{
|
||||
return $this->stringList('implementation_signals', self::IMPLEMENTATION_SIGNALS);
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getRoiSignals(): array
|
||||
{
|
||||
return $this->stringList('roi_signals', self::ROI_SIGNALS);
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
private function stringList(string $key, array $default): array
|
||||
{
|
||||
$value = $this->config[$key] ?? $default;
|
||||
if (!is_array($value)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($value as $item) {
|
||||
if (!is_scalar($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = trim((string) $item);
|
||||
if ($item === '' || in_array($item, $out, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$out[] = $item;
|
||||
}
|
||||
|
||||
return $out !== [] ? $out : $default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,67 @@ namespace App\Config;
|
||||
|
||||
final class SearchRepairConfig
|
||||
{
|
||||
private const GENERIC_CANDIDATE_TOKENS = [
|
||||
'wasser',
|
||||
'messgerät',
|
||||
'messgeraet',
|
||||
'produkt',
|
||||
'geräte',
|
||||
'geraete',
|
||||
'gerät',
|
||||
'geraet',
|
||||
'resthärte',
|
||||
'resthaerte',
|
||||
'preis',
|
||||
'infos',
|
||||
'wissen',
|
||||
];
|
||||
|
||||
private const ACCESSORY_CANDIDATE_TERMS = [
|
||||
'indikator',
|
||||
'indicator',
|
||||
'reagenz',
|
||||
'reagent',
|
||||
'kit',
|
||||
'set',
|
||||
];
|
||||
|
||||
private const ACCESSORY_OR_BUNDLE_TERMS = [
|
||||
'passend',
|
||||
'passende',
|
||||
'zubehor',
|
||||
'zubehör',
|
||||
'dazu',
|
||||
'zusatz',
|
||||
'erganzung',
|
||||
'ergänzung',
|
||||
'indikator',
|
||||
'reagenz',
|
||||
'kit',
|
||||
'set',
|
||||
'auch\s+das',
|
||||
'mit\s+preis\s+und\s+allen\s+infos',
|
||||
];
|
||||
|
||||
private const SPECIFICITY_BOOST_TERMS = [
|
||||
'indikator',
|
||||
'indicator',
|
||||
'testomat',
|
||||
'tritromat',
|
||||
'titromat',
|
||||
'reagenz',
|
||||
'reagent',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly bool $enabled = true,
|
||||
private readonly int $maxRepairQueries = 3,
|
||||
private readonly int $minPrimaryResultsWithoutRepair = 2,
|
||||
private readonly array $config = [],
|
||||
private readonly ?DomainVocabularyConfig $vocabulary = null,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -58,26 +115,13 @@ final class SearchRepairConfig
|
||||
return '/\b(?:' . implode('|', $this->getSpecificityBoostTerms()) . ')\b/iu';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getGenericCandidateTokens(): array
|
||||
{
|
||||
return [
|
||||
'wasser',
|
||||
'messgerät',
|
||||
'messgeraet',
|
||||
'produkt',
|
||||
'geräte',
|
||||
'geraete',
|
||||
'gerät',
|
||||
'geraet',
|
||||
'resthärte',
|
||||
'resthaerte',
|
||||
'preis',
|
||||
'infos',
|
||||
'wissen',
|
||||
];
|
||||
return $this->stringList(
|
||||
'generic_candidate_tokens',
|
||||
$this->vocabularyView('search_repair.generic_candidate_tokens', self::GENERIC_CANDIDATE_TOKENS)
|
||||
);
|
||||
}
|
||||
|
||||
public function getSanitizeTrimCharacters(): string
|
||||
@@ -155,57 +199,61 @@ final class SearchRepairConfig
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getAccessoryCandidateTerms(): array
|
||||
{
|
||||
return [
|
||||
'indikator',
|
||||
'indicator',
|
||||
'reagenz',
|
||||
'reagent',
|
||||
'kit',
|
||||
'set',
|
||||
];
|
||||
return $this->stringList(
|
||||
'accessory_candidate_terms',
|
||||
$this->vocabularyView('search_repair.accessory_candidate_terms', self::ACCESSORY_CANDIDATE_TERMS)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getAccessoryOrBundleTerms(): array
|
||||
{
|
||||
return [
|
||||
'passend',
|
||||
'passende',
|
||||
'zubehor',
|
||||
'zubehör',
|
||||
'dazu',
|
||||
'zusatz',
|
||||
'erganzung',
|
||||
'ergänzung',
|
||||
'indikator',
|
||||
'reagenz',
|
||||
'kit',
|
||||
'set',
|
||||
'auch\s+das',
|
||||
'mit\s+preis\s+und\s+allen\s+infos',
|
||||
];
|
||||
return $this->stringList(
|
||||
'accessory_or_bundle_terms',
|
||||
$this->vocabularyView('search_repair.accessory_or_bundle_terms', self::ACCESSORY_OR_BUNDLE_TERMS)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getSpecificityBoostTerms(): array
|
||||
{
|
||||
return [
|
||||
'indikator',
|
||||
'indicator',
|
||||
'testomat',
|
||||
'tritromat',
|
||||
'titromat',
|
||||
'reagenz',
|
||||
'reagent',
|
||||
];
|
||||
return $this->stringList(
|
||||
'specificity_boost_terms',
|
||||
$this->vocabularyView('search_repair.specificity_boost_terms', self::SPECIFICITY_BOOST_TERMS)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
private function vocabularyView(string $path, array $fallback): array
|
||||
{
|
||||
return $this->vocabulary?->view($path, $fallback) ?? $fallback;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
private function stringList(string $key, array $default): array
|
||||
{
|
||||
$value = $this->config[$key] ?? $default;
|
||||
if (!is_array($value)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($value as $item) {
|
||||
if (!is_scalar($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = trim((string) $item);
|
||||
if ($item === '' || in_array($item, $out, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$out[] = $item;
|
||||
}
|
||||
|
||||
return $out !== [] ? $out : $default;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user