Problem/Motivation

Perhaps this should be a task, or maybe it will turn into one. I'm trying to index a commerce product multiple times. Each time for each product color. Color is a field on the product (not the variation) as variations differ by price but the color of the product doesn't effect the price at all.

So, given this is a field on the product and my desire to index each product multiple times... how does one do that? I started looking into a solution via hook_search_api_index_items_alter. That doesn't really work too well as it breaks batch when I clone and add new documents to the list of document to index. So then I looked at creating a custom ContentEntity that forked out new documents. That became troublesome due to the way that item ids are calculated and inherent meaning stored in the. Meaning that is calculated in lots of different places, but all using the same idea of colon separated values that include the entity_type:entity_id:langcode.

Then I noticed that we also calculate that "hash" over in Index too. Then I gave up and said to myself, is indexing the same product multiple times even really possible? Sure I could alter in new URLs pretty easily for each of the documents. i.e. /product/1?color=yellow, /product/1?color=green, etc. But I can't figure out an easy way to create the new documents in the first place.

Proposed resolution

Help

Remaining tasks

???

Comments

heddn created an issue. See original summary.

heddn’s picture

Issue summary: View changes
mkalkbrenner’s picture

Project: Search API Solr » Search API
Version: 8.x-2.x-dev » 8.x-1.x-dev
Component: Code » General code

This question isn't specific for the Solr backend.
One solution might be to create a custom Search API datasource.
Using the entity datasource you have the language as variation. You need the color.

drunken monkey’s picture

Component: General code » Plugins
Status: Active » Fixed

As you have already surmised, you need to create your own datasource plugin (see docs – sadly not very detailed at the moment), probably easiest by inheriting from ContentEntity.
As the item IDs, you can for instance just add another colon and then the color to the existing ones – 1:en:red, for instance (or, more probably, the taxonomy term ID for “red” instead). In getPartialItemIds() you’d then not only create variants per language, but also per color. Most of the rest, you can probably keep as is, just item loading will also need to be adapted. (Not really sure how to best do that, as you’ll likely want to remove all other colors from the entity for that – maybe you need to provide your own ComplexDataInterface implementation to solve this clearly. (Just cloning the entity object and removing the other color values might also work, but could be dangerous regarding accidentally saving such a modified entity.)

Hope this helps!

(Side note, regarding the question in the title: As we already index entities multiple times (once per language) you know this is possible. And our provided ContentEntity datasource plugin does nothing that wouldn’t be possible for third-party plugins, too.)

heddn’s picture

That hash thing (item id) seems embedded all over the place. In solr, search_api. And it assumes the last value is langcode, 2nd is entity type, etc. Are we sure this has been done and it is possible?

drunken monkey’s picture

I’m just answering regarding the Search API side of things. I can at least assure you that it will work fine in all modules I maintain.
Other modules (like the Solr backend) are a different matter, I’ve already come across a few places that incorrectly assume item IDs of a certain format. If you run into problems regarding that, you’d have to file an issue with the respective module.

However, if I understand correctly what you’re referring to, then the “hash thing” is just a site-specific prefix for the Solr-internal ID, it has nothing to do with the Search API item IDs or how Solr assumes the rest of the ID will look.

And it assumes the last value is langcode, 2nd is entity type, etc.

The latter is an entirely different thing: item IDs in the Search API are composed of two different parts, separated by a slash – that much is indeed hard-coded. The first is the datasource plugin ID – e.g., entity:node for the built-in “Content” datasource (a derivative of the generic entity base plugin). The second part – ENTITY_ID:LANGCODE for the built-in datasources – is the datasource-specific item ID, and it should be entirely up to the datasource to define.
So, the methods in your datasource plugin would only deal the second part of item IDs – the first part, as handled by the rest of the Search API framework, will always be yourdatasourcepluginid/.

But if the Solr backend indeed assumes somewhere that the second part of the item ID is a langcode (and that it’s separated by a colon), then that is indeed a bug which you should report.

heddn’s picture

Thank you for all your help here. I ended up figuring out I was doing this wrong. Each of the color swatches are on a paragraph, along with an example product photo in that color. So instead of anything complicated, I realized (with all of your assistance) that if I index commerce products and my color swatch paragraphs. Then render up both of these and their facets in a view. In views I had to filter out products that do not have an empty color swatch paragraph. Because there are some products in the catalog that are colored and some that don't color swatches. This way I don't display the same items in the products search page twice. I just display the paragraphs + products without any color swatches. To render the color swatched, correctly I just preprocessed the paragraphs to add the parent product's rendered fields and themed out the search index view mode in twig to "look" like a product.

TLDR; thanks for you help.

Status: Fixed » Closed (fixed)

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