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
Comment #2
heddnComment #3
mkalkbrennerThis 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.
Comment #4
drunken monkeyAs 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). IngetPartialItemIds()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 ownComplexDataInterfaceimplementation 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
ContentEntitydatasource plugin does nothing that wouldn’t be possible for third-party plugins, too.)Comment #5
heddnThat 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?
Comment #6
drunken monkeyI’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.
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:nodefor the built-in “Content” datasource (a derivative of the genericentitybase plugin). The second part –ENTITY_ID:LANGCODEfor 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.
Comment #7
heddnThank 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.