(note this issue is for the 8.0.x and 9.0.x release series; see #2980257: Type-specific boosting is being ignored completely with elasticsearch_connector for the 8.x-7.x release series)

Problem/Motivation

We are attempting to use the "Type-specific boosting" feature of Search API in combination with elasticsearch_connector, and it turns out that this is not working at all. I'm not even sure if it was ever implemented in the code.

We can change the weights from anything from 0.0 to 21.0, then reindex all of our data after clearing everything out, and the scores/relevance that comes back always remains the EXACT same value, regardless of what we set those values to.

This is a fairly big issue on a large site we are about to launch, as we really need a way to have certain content types almost always appear higher up in search, in general, of course.

Proposed resolution

Add a Search API Processor plugin to configure Elasticsearch function_score queries.

Remaining tasks

  1. Merge request for 8.0.x - merge request !165 created by @andyg5000 in #5
  2. Add tests - done by @mparker17 by #12
  3. Maintainer review - done by @mparker17 by #12
  4. Merge request for 9.0.x - merge request !199 created by @mparker17 in #14
  5. Community review - skipped by @mparker17 in #16
  6. Commit to 9.0.x - merged by @mparker17 in #17
  7. Commit to 8.0.x - merged by @mparker17 in #19
  8. Release 9.0.x - released in 9.0.0-alpha3 by @mparker17
  9. Release 8.0.x - released in 8.0.0-alpha7 by @mparker17

User interface changes

Adds a "Type-specific boosting (Elasticsearch)" Search API Processor option available at /admin/config/search/search-api/index/YOUR_INDEX/processors. This processor runs at Preprocess query time, with a details element for each Search API Datasource defined for the Index, and controls to set a default boost for that datasource, as well as all bundles known to that datasource.

Introduced terminology

None.

API changes

API additions only: adds a SearchApiProcessor plugin with the machine name elasticsearch_type_boost, which runs in the preprocess_query stage.

Data model changes

Adds configuration in the plugin.plugin_configuration.search_api_processor.elasticsearch_type_boost namespace (in Index configuration).

Release notes snippet

Add a Search API Processor to support type-specific boosting using Elasticsearch Function score queries.

Original report by @andyg5000

Duplicate of #2980257: Type-specific boosting is being ignored completely with elasticsearch_connector, but tracking 8.x

Elasticsearch 7.x has reached End-Of-Life. I'm happy to move this work over to that issue, but didn't want to mess up anyone since there was already a merge request from @mparker17 recently.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

andyg5000 created an issue. See original summary.

andyg5000’s picture

Status: Active » Closed (duplicate)

Ah, I can create a new branch on the older issue :D

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

andyg5000’s picture

Status: Closed (duplicate) » Needs review

Ok, never mind I can't do that 😅 Opening this back up and setting to needs review. It's the same approach but applies to 8.0.x-dev.

andyg5000’s picture

mparker17’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests, +Needs issue summary update

@andyg5000, thanks!


It looks like we're getting a test failure in the \Drupal\Tests\elasticsearch_connector\Unit\SearchAPI\Query\QueryParamBuilderTest::testBuildQueryParams() test.

Specifically the mock query object isn't expecting the new call to getOption('elasticsearch_connector_type_boost_functions') added in the patch. You'll probably have to add something like...

@@ -74,6 +74,8 @@
       ->willReturn($fields);
 
     $query = $this->prophesize(QueryInterface::class);
+    $query->getOption('elasticsearch_connector_type_boost_functions')
+      ->willReturn([]);
     $query->getOption('offset')
       ->willReturn(0);
     $query->getOption('limit')

... to fix that test.


QueryParamBuilderTest::testBuildQueryParams() is only supposed to test a basic flow through QueryParamBuilder::buildQueryParams(), so you'll also need to add a separate test where getOption('elasticsearch_connector_type_boost_functions') returns something, and then checking that the query is modified in the way that you expect. I recommend testing your specific use-case in this separate test, so that you can be confident that future changes to the module won't cause your use case to regress!

mparker17’s picture

Title: 8.x | Type-specific boosting is being ignored completely with elasticsearch_connector » Support type-specific boosting with a processor to configure function_score queries (8.0.x and 9.0.x)
Category: Bug report » Feature request
Issue summary: View changes
Issue tags: -Needs issue summary update

Finally getting back to this issue after a while; sorry for the delay, and thank you in advance for your patience with me.

I haven't had a chance to rebase, re-review the code, or fix the test... just updating the issue summary with all the details so that I don't have to hop between this issue and #2980257: Type-specific boosting is being ignored completely with elasticsearch_connector; and also for documentation purposes (i.e.: for folks who stumble across this issue in the release notes / future). Thanks for understanding!

mparker17’s picture

We are attempting to use the "Type-specific boosting" feature of Search API in combination with elasticsearch_connector, and it turns out that this is not working at all. I'm not even sure if it was ever implemented in the code.

Some notes on what happened here...

Search API Processor plugins can run at three different stages: Preprocess index (i.e.: when content is being indexed, i.e.: copied to Elasticsearch), Preprocess query (before a search query is sent to the server), and Postprocess query (after a search query response is received, before displaying results).

The Type-specific boosting processor (\Drupal\search_api\Plugin\search_api\processor\TypeBoost, machine name type_boost) is built into Search API (i.e.: upstream from Elasticsearch Connector) but - at time-of-writing - it is still hard-coded to run at Preprocess index time.

The problem is that, beginning in Elasticsearch 5.0.0 (released in 2016), boosting at index-time was deprecated; but it still worked on indexes created before Elasticsearch 5.0.0 until at least Elasticsearch 7.11, but it was completely removed in Elasticsearch 8.0.0.

TL;DR this means that Search API's Type-specific boosting plugin stopped working for new sites around Elasticsearch 5.0.0 / 2016; but may have continued to work for existing sites depending on how they managed their indexes.

@sokru, @siliconvalet, @sonnykt, @tvosenek, @a.dmitriiev, @ebeyrent, and myself removed some other vestiges of index-time boosting in #3183164: Index-time boost is deprecated / merge request !1.

mparker17’s picture

I was wondering if it was possible to hide Search API's upstream TypeBoost (type_boost) processor for Indexes with a Server with an Elasticsearch backend. It is possible to hide it (by subscribing to \Drupal\search_api\Event\GatheringPluginInfoEvent), but not for a specific Index/Server/Backend. Likewise, it's possible to alter the class associated with that plugin definition, and/or change the stages associated with the plugin definition... but again, not for a specific Index/Server/Backend.

(I don't want to assume that site builders only have one Search API Server backend enabled on their site at one time - perhaps they're evaluating multiple search backends to see which fits their use-case, or perhaps they're transitioning to/from Elasticsearch)


Anyway, all this is to say that I'm satisfied with the solution in this patch, i.e.: of providing a clearly-marked, Elasticsearch-specific processor plugin for this plugin.

mparker17’s picture

Issue summary: View changes

The test failure we're seeing in Drupal\Tests\elasticsearch_connector\Unit\SearchAPI\Query\QueryParamBuilderTest::testBuildQueryParams() has to do with test doubles (a technique used for writing unit tests). I wrote a longer explanation of test doubles in #3542571-10: Add OriginalIndexId to IndexParamsEvent earlier today (see that comment for more information).

Similar to how we fixed the test in 3542571, we'll have to update the mock QueryInterface to expect a call to getOption('elasticsearch_connector_type_boost_functions', [])).

But, unlike 3542571, there is no other test coverage for function_score queries, or (elasticsearch_)?type_boost plugins, so we'll still need to write a test for the functionality added in this patch before I can merge it (tests will ensure that the functionality your site depends on won't break in the future as new patches are accepted).

mparker17’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

Okay, I've added tests, and this is ready for community review: @andyg5000, would you be able to re-test the patch to ensure it still works? If so, please change the issue status to "Reviewed & tested by the community"

Some steps for manual testing...

  1. Set up a local 8.0.x environment
  2. Log in as an administrator.
  3. Go to /test-elasticsearch-index-search. Under Fulltext search = foo, then click the Apply button. Look at the 0 ID column: the rows should be in the order 4, 2, 5, 1. Note also the 5 Category column: the rows should be in the order article_category, item_category, article_category, item_category, i.e.: reflecting roughly equal boosts to every content type. Note also the numbers in the 1 Relevance column; they should be pretty close to each-other.
  4. Go to /admin/config/search/search-api/index/test_elasticsearch_index/processors. Under Enabled, check Type-specific boosting (Elasticsearch). Scroll down to Processor settings, and open the Type-specific boosting (Elasticsearch) vertical tab. Set Default boost for items from this datasource = 1.00. Set Boost for the Entity Test Bundle bundle to 1.00. Set Boost for the item bundle = 21.00. Set Boost for the article bundle = 1.00. Click the Save button.
  5. Go to /test-elasticsearch-index-search. Under Fulltext search = foo, then click the Apply button. Look at the 0 ID column: the rows should be in the order 2, 1, 4, 5. Note also the 5 Category column: the rows should be in the order item_category, item_category, article_category, article_category, suggesting the 21.00 boost to the item content type is giving items a bigger boost. Note also the numbers in the 1 Relevance column; the two items should have much larger relevance than the articles.

I will create a merge request for the 9.0.x branch shortly.

mparker17’s picture

Issue summary: View changes

(updating issue summary)

mparker17’s picture

Version: 8.0.x-dev » 9.0.x-dev
Issue summary: View changes
Issue tags: +needs backport to 8.0.x

Created a 9.0.x merge request. Added a tag so I remember to merge the 8.0.x branch too.

mparker17’s picture

Issue summary: View changes

I haven't heard back from anyone in 7 days, but I want to include this change in the next release, so I'm going to merge this without community review.

  • mparker17 committed 708fe5cb on 9.0.x
    feat: #3567158 Support type-specific boosting with a processor to...
mparker17’s picture

Version: 9.0.x-dev » 8.0.x-dev
Issue summary: View changes
Status: Needs review » Patch (to be ported)
Issue tags: -needs backport to 8.0.x

Merged to 9.0.x; merging to 8.0.x next.

  • mparker17 committed 85156000 on 8.0.x authored by andyg5000
    feat: #3567158 Support type-specific boosting with a processor to...
mparker17’s picture

Issue summary: View changes
Status: Patch (to be ported) » Fixed

Merged to 8.0.x. I'll update this issue when these code changes are released.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

mparker17’s picture

Issue summary: View changes

The changes in this issue were released in elasticsearch_connector-9.0.0-alpha3, and elasticsearch_connector-8.0.0-alpha7

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.