How can I conditionally alter search API relevance score? I must be missing some core concept of search API somehow, but I am stuck. The goal is to alter search API results depending on a flag, like Give flagged products in search API a higher search score? however this time without SOLR, but with database backend instead.

I can see all flagged fields properly indexed, so there is a line that associates the content entity id with the user who flagged, and now I want to increase the relevance score of the results, so that items flagged by the current user are always shown first. 

I have hijacked the SearchApiDbService class and I did add the following line in postQuery (I also wonder why this hook does not exist, but that is not relevant for now):     

drupal_alter('search_api_db_query_results', $results, $query);


This should allow me to alter the search results right before search_api_db hands them over to the search API right?

So now I use the alter hook as follows:

function mymodule_search_api_db_query_results_alter(&amp;$results, SearchApiQueryInterface $query) {
  global $user;
  $uid = $user-&gt;uid;

  // Fetch a list of content entities that the user has flagged.
  $drupal_db_q = db_select('search_api_db_MY_FLAG_FIELD_TABLE', 'f')
    -&gt;fields('f')
    -&gt;condition('value', $uid);
  $items = $drupal_db_q-&gt;execute()-&gt;fetchCol();

  // Iterate over results and multiply score of flagged items.
  foreach ($results['results'] as $key =&gt; &amp;$result) {
    if (in_array($key, $items)) {
      $result['score'] *= 10;
    }
  }

dpm($results);

}


In $results I can see that the scores have changed, but the order of the items on my views results page has not, even though I am sorting by relevance.

It has to be something simple, or I am completely misunderstanding how the score value works somehow?

p.s. Since this is conditionally I don't think altering the search api query directly makes sense because I found no way to boost any field scores there. Directions on how to achieve that are welcome too.
Since everyone was telling me to solve this during the query, I decided to have another look at this approach. My main issue was not being able to order by the flagged status, which was eventually solved with an expression. 

In the end I managed to get what I wanted with an implementation of hook_search_api_db_query_alter.

function mymodule_search_api_db_query_alter(SelectQueryInterface &amp;$db_query, SearchApiQueryInterface $query) {
  global $user;
  $uid = $user-&gt;uid;

  // Left join indexed flag table into search index.
  $db_query-&gt;leftJoin('search_api_db_product_index_field_my_flag_field', 'flag', 'flag.item_id = t.item_id');
  // Set a value of 1 for entities flagged by the given uid, 0 otherwise. 
  $alias = $db_query-&gt;addExpression('CASE WHEN flag.value = :uid THEN 1 ELSE 0 END', 'flagged', array(':uid' =&gt; $uid));
  // Order by the flagged value (1 or 0), highest first.
  $db_query-&gt;orderBy($alias, 'DESC');
}