Add hook_ai_search_results_alter() to allow other modules to modify or re-rank AI search results
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3556016. -->
Reported by: [nnevill](https://www.drupal.org/user/835208)
Related to !992 !993
>>>
<p>Currently, the AI Search processor in the ai_search module executes the search query and returns scored entity results directly.<br>
There is no way for other modules to adjust or re-rank these results before they are returned.</p>
<p>This issue introduces a new hook:</p>
<p><code>hook_ai_search_results_alter(array &$results, $keywords)</code></p>
<h4>Purpose</h4>
<p>The new hook allows other modules to:</p>
<ul>
<li>Adjust or boost relevance scores for specific entities (e.g., promote certain content types).</li>
<li>Filter or remove results.</li>
<li>Reorder results based on custom business logic.</li>
</ul>
<h4>Example Implementation</h4>
<div class="codeblock">
<pre><span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #007700">function </span><span style="color: #0000BB">mymodule_ai_search_results_alter</span><span style="color: #007700">(array &</span><span style="color: #0000BB">$results</span><span style="color: #007700">, </span><span style="color: #0000BB">$keywords</span><span style="color: #007700">): </span><span style="color: #0000BB">void </span><span style="color: #007700">{<br> </span><span style="color: #FF8000">// Example: Boost a specific node manually.<br> </span><span style="color: #007700">if (isset(</span><span style="color: #0000BB">$results</span><span style="color: #007700">[</span><span style="color: #DD0000">'entity:node/8215:en'</span><span style="color: #007700">])) {<br> </span><span style="color: #0000BB">$results</span><span style="color: #007700">[</span><span style="color: #DD0000">'entity:node/8215:en'</span><span style="color: #007700">] += </span><span style="color: #0000BB">0.2</span><span style="color: #007700">;<br> }<br><br> </span><span style="color: #FF8000">// Example: Slightly boost all "article" nodes.<br> </span><span style="color: #007700">foreach (</span><span style="color: #0000BB">$results </span><span style="color: #007700">as </span><span style="color: #0000BB">$entity_id </span><span style="color: #007700">=> </span><span style="color: #0000BB">$score</span><span style="color: #007700">) {<br> if (</span><span style="color: #0000BB">preg_match</span><span style="color: #007700">(</span><span style="color: #DD0000">'/^entity:node\/(\d+)/'</span><span style="color: #007700">, </span><span style="color: #0000BB">$entity_id</span><span style="color: #007700">, </span><span style="color: #0000BB">$matches</span><span style="color: #007700">)) {<br> </span><span style="color: #0000BB">$nid </span><span style="color: #007700">= (int) </span><span style="color: #0000BB">$matches</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">];<br> </span><span style="color: #0000BB">$node </span><span style="color: #007700">= \</span><span style="color: #0000BB">Drupal</span><span style="color: #007700">::</span><span style="color: #0000BB">entityTypeManager</span><span style="color: #007700">()-></span><span style="color: #0000BB">getStorage</span><span style="color: #007700">(</span><span style="color: #DD0000">'node'</span><span style="color: #007700">)-></span><span style="color: #0000BB">load</span><span style="color: #007700">(</span><span style="color: #0000BB">$nid</span><span style="color: #007700">);<br> if (</span><span style="color: #0000BB">$node </span><span style="color: #007700">&& </span><span style="color: #0000BB">$node</span><span style="color: #007700">-></span><span style="color: #0000BB">bundle</span><span style="color: #007700">() === </span><span style="color: #DD0000">'article'</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$results</span><span style="color: #007700">[</span><span style="color: #0000BB">$entity_id</span><span style="color: #007700">] = </span><span style="color: #0000BB">$score </span><span style="color: #007700">+ </span><span style="color: #0000BB">0.05</span><span style="color: #007700">;<br> }<br> }<br> }<br><br> </span><span style="color: #0000BB">arsort</span><span style="color: #007700">(</span><span style="color: #0000BB">$results</span><span style="color: #007700">);<br>}<br></span><span style="color: #0000BB">?></span></span></pre></div>
<p><strong>Developer Notes</strong></p>
<ul>
<li>The hook is invoked in the AiSearchProcessor::getAiSearchResults() method right before returning the $ai_entity_ids.</li>
<li>It follows Drupal’s standard alter pattern.</li>
<li>Example usage is documented in ai_search.api.php.</li>
<li>
</ul>
<p><strong>Benefits</strong></p>
<ul>
<li>Extensibility: enables contrib and custom modules to influence AI ranking logic.</li>
<li>Better integration with site-specific or domain-specific relevance tuning.</li>
<li>Non-breaking change: existing functionality remains unaffected unless the hook is implemented.</li>
</ul>
issue