Skip to content

Instantly share code, notes, and snippets.

@meminuygur
Created September 10, 2025 08:10
Show Gist options
  • Select an option

  • Save meminuygur/e987fcae05a46ff92cd64b25bcf2201d to your computer and use it in GitHub Desktop.

Select an option

Save meminuygur/e987fcae05a46ff92cd64b25bcf2201d to your computer and use it in GitHub Desktop.
public function hybridSearch($collectionName, $query, array $queryVector, $additionalParams = [], $recursionDepth = 0)
{
$client = $this->getTypesenseClient();
$totalResultRequested = $additionalParams['k'] ?? 100;
$distanceThreshold = $additionalParams['distance_threshold'] ?? 0.7;
$searchParams = array_merge([
'q' => $query,
'query_by' => $this->helper->getKeywordFieldsByCollection($collectionName),
'query_by_weights' => $this->helper->getQueryByWeight($collectionName),
'vector_query' => 'embedding_vector:([' . implode(',', $queryVector) . '], k:' . $totalResultRequested . ', alpha:0.6, distance_threshold:'.$distanceThreshold.')',
'per_page' => $additionalParams['per_page'] ?? 20,
'exclude_fields' => 'embedding_vector',
'rerank_hybrid_matches' => true,
'drop_tokens_threshold' => 0,
'sort_by' => '_text_match:desc',
'prioritize_exact_match' => true,
], $additionalParams);
$entityType = $this->helper->extractEntityType($collectionName);
if($entityType === 'product') {
$attributeSetId = Data::WALLPAPER_ATTRIBUTE_SET;
if(preg_match('/sticker|decal/i', $query)) {
$attributeSetId = Data::WALLDECAL_ATTRIBUTE_SET;
}
$textMatchPrioritized = false;
$rankingScorePrioritized = false;
$wordCount = str_word_count($query);
if($wordCount === 1) {
$rankingScorePrioritized = true;
} else {
foreach ($this->helper->getRankingScorePrioritizedKeywords() as $rankingScorePrioritizedKeyword) {
if (stripos($query, $rankingScorePrioritizedKeyword) !== false) {
$rankingScorePrioritized = true;
break;
}
}
}
foreach ($this->helper->getTextMatchPrioritizedKeywords() as $textMatchPrioritizedKeyword) {
if (stripos($query, $textMatchPrioritizedKeyword) !== false) {
$textMatchPrioritized = true;
}
}
if($rankingScorePrioritized) {
$searchParams['sort_by'] = '_eval(attribute_set:='.$attributeSetId.'):desc, ranking_bucket:desc, _text_match:desc';
} else {
$searchParams['sort_by'] = '_eval(attribute_set:='.$attributeSetId.'):desc, _text_match(buckets: 10):desc, ranking_score:desc';
}
if($textMatchPrioritized) {
$searchParams['sort_by'] = '_eval(attribute_set:='.$attributeSetId.'):desc, _text_match:desc, ranking_bucket:desc';
}
}
$multiSearchParams = [
'searches' => [
array_merge(['collection' => $collectionName], $searchParams),
]
];
$response = $client->getMultiSearch()->perform($multiSearchParams);
if(isset($response['results'][0]['found']) && $response['results'][0]['found'] < 5 && $recursionDepth === 0) {
$additionalParams['distance_threshold'] = 0.85;
return $this->hybridSearch($collectionName, $query, $queryVector, $additionalParams, $recursionDepth + 1);
}
return $response['results'][0] ?? [];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment