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 &amp;$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">&lt;?php<br></span><span style="color: #007700">function </span><span style="color: #0000BB">mymodule_ai_search_results_alter</span><span style="color: #007700">(array &amp;</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>&nbsp; </span><span style="color: #FF8000">// Example: Boost a specific node manually.<br>&nbsp; </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>&nbsp;&nbsp;&nbsp; </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>&nbsp; }<br><br>&nbsp; </span><span style="color: #FF8000">// Example: Slightly boost all "article" nodes.<br>&nbsp; </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">=&gt; </span><span style="color: #0000BB">$score</span><span style="color: #007700">) {<br>&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </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">()-&gt;</span><span style="color: #0000BB">getStorage</span><span style="color: #007700">(</span><span style="color: #DD0000">'node'</span><span style="color: #007700">)-&gt;</span><span style="color: #0000BB">load</span><span style="color: #007700">(</span><span style="color: #0000BB">$nid</span><span style="color: #007700">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (</span><span style="color: #0000BB">$node </span><span style="color: #007700">&amp;&amp; </span><span style="color: #0000BB">$node</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bundle</span><span style="color: #007700">() === </span><span style="color: #DD0000">'article'</span><span style="color: #007700">) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; }<br><br>&nbsp; </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">?&gt;</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&rsquo;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