Taxonomy synonyms used to be a feature in Drupal 6. They were dropped in Drupal 7, on the basis that synonym-like systems are easy to create using fields.
However, there doesn't seem to be any clear clean robust way I can see to get any system of taxonomy synonyms implemented with fields that works well with Facet API. Is there such a way? What would you recommend as the most robust, Facet-API friendly way to set up taxonomy synonyms?
Over at Drupal Answers, there's a question on this with a pile of examples of ways that taxonomy synonyms could potentially be done but which, for various reasons, don't quite cut it. (there's also a bounty on that question at the moment, so potentially free points for anyone answering it...).
To give a simple example, imagine a taxonomy where "Notebooks" is a synonym for "Laptops". You have a site with Facet API and Search API, and you want the following:
- Searches for 'Notebooks' to find results tagged with 'Laptops' (one way this could be done is with a 'synonyms' field on the vocabulary that is indexed in Search API with equal weight to the term's name)
- An autocomplete facet where someone typing in 'Notebooks' gets something that gives them content tagged with 'Laptops', not nothing (the detail of how doesn't matter too much), without being unweildy for the user (e.g. if a term had lots of synonyms)
- All the above works/doesn't break with common Facet API / Search API modules and features like Current Search blocks, Solr, etc
Comments
Comment #1
cpliakas commentedHi alanomaly.
I see a multi-pronged approach to this, although I honestly haven't thought much about this use case until now. First, I would add a term reference field to the taxonomy term to accomplish the synonyms, and then you have to implement the Search API hooks to ensure that the referenced taxonomy term IDs are indexed along with the base taxonomy term ID. Look to how the module indexes taxonomy with depth for guidance. At that point, Facet API will work as expected, in that clicking on the "Notebook" facet would also return content tagged with "Laptop".
Regarding the autocomplete, that is more of a widget question. You would have to build the widget to do that, which I am not sure exists yet. The endpoint for the autocomplete call would have to query the backend to get the available facets for the result set, which could get really expensive since it would have to execute a search query on every keystroke unless caching was utilized correctly. This gets tricky if you have things like node access in place or alter the query via hooks.
In terms of the searches for "Notebooks" matching "Laptops", that is more of a backend thing. For example, in Solr you can use the synonyms.txt file to define your synonyms which will accomplish your goals. Other backends will have different techniques.
Hope this helps a little,
Chris
Comment #2
alanom commentedGreat, thanks for the reply. I think this is the first time I've seen a drupal.org support request get an answer faster than a question on Drupal Answers! Much appreciated!
If it is a Search API Solr search and the notebook-laptop synonym is defined in the synonyms.txt file, would that alone be enough to cause a click on the Notebook link to return Laptop content? My understanding is that Facet API simply passes input and receives output from the search back end at this point, so I would imagine it would.
(You're right about autocomplete needing a whole new largely impractical widget - I got my modules mixed up, sorry! For that particular one I was thinking of Search API Views and exposed filters which is a whole different thing. I got them mixed up because I'd set up some custom JS to filter a long list of facets client side. Thanks for answering the question I should have asked about the facet link observing the synonym!)
Comment #3
cpliakas commentedalanomaly,
No problem. You caught me on a gardening day, where I can spend my time working on Drupal. Great day to ask a question :-).
No, I actually think it is a cool idea for a facet widget. It just doesn't exist AFAIK, but it would be a great add-on if it could be implemented properly. There are a few contributed widgets out there that have a pretty good UX, but none that match your description.
In terms of the synonyms.txt file, it actually wouldn't work for facets because the the Solr integration modules store the taxonomy term IDs, not the actual text. Therefore synonyms.txt doesn't pick that up and you have to explicitly add the term IDs. It honestly wouldn't be that much code to add the synonym IDs to the index, the trick will be making sure the data is mapped to the correct Solr field which is sometimes a bit tricky to figure out.
Chris
Comment #4
alanom commentedUseful information - can you elaborate on the last paragraph? I understand that the Drupal integration modules work with entities and the entity load system based on id and type, but at some the Solr java (or whatever alternate engine is being used) must be fed text to work.
I don't quite understand your last sentance - are you talking about a term reference field on a term, which, in Search API, loads and indexes the other term's name? If so, yes that's not hard and can be done in the Search API UI, however there are probable issues with this approach noted on the Drupal Answers question and the (currently untouched) Search API version of this support request:
Term references only go one way - so unless each synonym was inputed twice both ways (or n(n+1) ways where there are n synonyms in a cluster), or if something heavy duty like Relation was used, if 'Laptop' is the main tag and 'Notebook' the less favoured synonym, 'Notebook' would find 'Laptop' content without trouble but 'Laptop' wouldn't find any content mistakenly tagged 'Notebook'. Also, if people were dilligent in their tagging, I would expect someone clicking on a "Notebook" facet to find nothing as the second field would be wholly different index field seperate to the Taxonomy Term indexing - unless something like Search Api Combined was used to tell Search API / Facet API to treat these two fields as one?. Theoretically, something using Relation and Search API Combined might be able to be made to work, but that seems like a lot of quite heavy duty extra contrib modules, and a lot of potential breaking points, which makes me think I must be on the wrong lines somewhere.
(p.s. I agree that autocomplete facets could be awesome as a seperate issue)
(p.p.s. is working on Drupal while gardening like programming on a boat?)
Comment #5
cpliakas commentedYes. The "text" that is fed to Solr for taxonomy terms is actually their numeric IDs, not the actual term name. Therefore you probably wouldn't want to add numbers to the synonyms.txt file, because other numerics are indexed such a the node ID which might cause unexpected results. So for example, if you added a synonym of TID 5 to TID 5, the synonyms.txt file is global so it would also think the node ID 5 would equal node ID 1.
Ah, yes. If that is your use case, then you will have to use another module that does two way relationships or simply bypass the field system and code something up yourself which might actually be lighter, but not a trivial task.
The trick here is just getting the data into the index, then facets will work as expected no problem. But as you mentioned, unfortunately there are a lot of different ways to do this, most of which introduce a lot of moving parts and a fair amount of complexity. Unfortunately I am probably not the best person to give advice on this specific use case, since I haven't had to build a synonym solution with D7. Once you have the data and need to get it into the index, Search API is probably the place to go. When you want to facet on it, I am your guy.
Sounds like a boatload of awesome, is what it sounds like. Love hearing what other hobbies Drupalists have.