I'm not entirely sure if this problem stems from Search API or Views or Search API's Views integration, the problem manifests itself in my Solr query so I will raise it here and see what happens.
I have a view on a search_api_solr index with the following filters:
group 1 (exposed):
Fulltext Search
AND
group 2 (not exposed):
type='object' OR
type='publication'
which should result in q="searchterms"&fq=type:"object" OR "publication"
however it results in q="searchterms"&fq=type:"object"&fq=type:"publication"
To get around this I am hacking it in query_alter but I would like to be able to arrange the filters in Views without having to intercept them.
Am I missing some trick here or should my view work as it is?
Thanks in advance. :)
Comment | File | Size | Author |
---|---|---|---|
#18 | 1198754--views-filter-groups-18.patch | 8.19 KB | drunken monkey |
#17 | 1198754--views-filter-groups-17.patch | 7.99 KB | drunken monkey |
#14 | search-api-nested-conjunctions-1198754-14.patch | 5.16 KB | Anonymous (not verified) |
#2 | drupal_views_filter_group1.jpg | 34.69 KB | zenlan |
Comments
Comment #1
drunken monkeyHm, for me, this works as expected.
I'd also think the problem most likely lies in the Search API module and its Views integration, not in the Solr-specific module. (As a test, if you don't have too many nodes, you can create a database server, move the index to it, re-index and see if that solves the problem.)
You mean you have a filter on the type, and selected those two options?
Which version of the Search API are you using?
Comment #2
zenlan CreditAttribution: zenlan commentedThanks for responding.
Search API 7.x-1.0-beta10
I set up a test on the drupal index (my example above was using a custom entity index) and attached a screenshot from the views filter group configuration.
Search API Solr ends up with the following Solr query which cannot produce any results as there are no content types that are both page AND article:
http://localhost:8080/solr/drupal/select?qf=t_title&qf=t_body:value&fq=s..."article"&fq=ss_type:"page"&fq=index_id:my_solr_index_drupal&sort=score desc&version=1.2&wt=json&json.nl=map&q="searchterms"&start=0&rows=10
If I tweak the query in the browser, using 'OR' to conjoin the fq terms, (page OR article) I get results:
http://localhost::8080/solr/drupal/select?qf=t_title&qf=t_body:value&fq=(ss_type:"article" OR ss_type:"page")&sort=score%20desc&version=1.2&wt=json&json.nl=map&q="searchterms"&start=0&rows=10
Hope that helps.
Comment #3
drunken monkeyAh, judging from your screenshot the solution is quite simple: Search API doesn't support Views filter groups. Just use a normal filter on type and select both types as the filter values. That should work like expected.
Comment #4
zenlan CreditAttribution: zenlan commentedI have no requirement to do this for the Drupal index, that was just an example. I have this requirement for a read-only non-Drupal index and there is no filter of that sort for it. I would have to get the option-values from Solr in order to build the filter widget, which I was hoping to avoid.
Are there any other Views features that are not supported by Search API, are they documented somewhere?
Comment #5
drunken monkeyHonestly, I don't know. I didn't even know about filter groups until now (or, had only heard them mentioned once or twice, in passing). As I see it, there are numerous extensions for Views (both built-in and in extension modules) that are still pretty hardcoded for the default backend, or other Views defaults, which the Search API (and other systems) replaces. These extensions then won't work with Search API views, without us having really the chance to know about them, or tell the user they aren't working. (The "Global: Random" sort would be another example that popped up just one or two days ago.)
Also, when I wrote the Views integration, there was close to zero documentation for Views 3, and some inline documentation was also simply wrong. Don't know if that has improved since then, but it's also a reason why some more fancy features might not be supported by the Search API Views integration.
Comment #6
zenlan CreditAttribution: zenlan commentedFair enough, I feel your pain about the Views 3 documentation for sure. :)
I can live with my query_alter hack for now and if I get some spare time I'll try to take a deeper look, see if there is a proper solution.
Thanks and have a nice weekend. :)
Comment #8
Anonymous (not verified) CreditAttribution: Anonymous commented@zenlan, I have a similar issue, can you share your query_alter hack please?
Comment #9
Anonymous (not verified) CreditAttribution: Anonymous commentedI can see how to alter the global conjunction in a hook_search_api_query_alter(), like:
But how to create separate groups?
This is what I'm trying to achieve:
(brand=puma AND sku=123) OR (EAN=456)
Comment #10
Anonymous (not verified) CreditAttribution: Anonymous commentedJust my thoughts on this: both MySQL and Solr would support "nested conjunctions", so I think this is a valuable addition to Search API.
In the case of Apache Solr, it simply comes down to rewriting
createFilterQueries
.Views 3 stores the conjunction grouping like:
We could allow setConjunction to have such an array.
This could be passed on the createFilterQueries ($filter).
Let me see if I can come up with a patch for this. Something like this
- search_api_views passes on the filter_groups operators
- search_api allows setConjunction to be an array()
- in createFieldsQuery functions, if conjunction is and array, then it walks through the groups and returns the correct query
Comment #11
zenlan CreditAttribution: zenlan commentedHello,
unfortunately my hack is very specific to one particular query where the 'OR' group has known fields so it won't be very useful to anyone else. A proper patch would be desirable but alas deadlines are looming and I have little spare time at the moment, although I could probably test and tweak if that would help.
Comment #12
drunken monkeyThe Search API already supports nested filters with different conjunctions (if you weren't aware of that). The problem is just that Views 3 documentation is sparse, to say the least, and I had no idea that there even were filter groups when I implemented the Views integration, let alone how they work (which I still don't know).
If you know what the filter handler has to check in the
query()
function, I could probably easily add this (once I have the time), or guide you on how to add this.Basically, to add a new filter group that hasn't got an AND conjunction, you call
$query->createFilter('OR')
, fill it with the conditions and then pass it to$query->filter()
– almost exactly what you'd do for a database query.Changing a filter's conjunction (especially the one on the base level) is highly discouraged, on the other hand.
Comment #13
Anonymous (not verified) CreditAttribution: Anonymous commentedThanks for the tips. I'm working on this today, will post back later.
Comment #14
Anonymous (not verified) CreditAttribution: Anonymous commentedHi,
attached is a patch which works for me. The patch focuses on
handler_filter.inc
and adds new logic to thequery()
function. That still needs adaptation for all otherhandler_filter_*.inc
.The new code creates nested conjunction filters. It is based on Views' "filter_groups" and passes on the
$group
level to thecondition()
functions, which now have a 4th argument$group = NULL
.In Search API's
query.inc
I added a check for$group
to add filters into the new filter groups. This only influences Views' queries, or falls back to default.Indeed. Therefore I added an extra nesting wrapper. Like so:
So there is 3 filter levels, Views. In my case, the resulting Solr
$fq
becomes perfectly:@todo: make the
handler_filter.inc
code more general for allhandler_filter_*.inc
files.@todo: prepare for even more nested levels? (Views only has 1 level of filter groups)
Comment #15
drunken monkeyGreat job, thanks a lot! I'm sorry I can't test/review right now, as I'm completely buried in work, but I'll get back to this issue ASAP.
Comment #16
Anonymous (not verified) CreditAttribution: Anonymous commentedNo problem at all, take it easy ;)
I just realized that my patch only works for 2 filter groups, for example:
((A OR B) AND* (C OR D))
I didn't think about 3 or more groups:
((((A OR B) OR* (C AND D)) AND* E) OR* (F AND G))
...and then imagine nested groups as well:
((((A OR B) OR* ((C AND D) OR** (H OR I))) AND* E) OR* (F AND G))
* = Views filter groups conjunction
** = nested groups (not supported by Views, but has potential for Search API to do complex queries)
This is getting really complex as you see... If I have free time, I will work more on this. I'd like to help make Search API the most powerful search tool for Drupal.
Comment #17
drunken monkeyOK, I finally managed to look at this.
First off, thanks again for helping with this! Your code made it pretty clear what was to do, and it also already seemed to work quite well. However, I think having this functionality bundled centrally in the Views query class is the best way to do this. We can care about creating the needed nested filters there, when they are needed, and keep changes to the filter handlers at a bare minimum.
Please see, test and review the attached patch. Sorry that there are some cosmetic changes (
array_shift()
=>reset()
; comment changes) in there, too. The main thing is I added the filter group to all calls tocondition()
andfilter()
, there just collected the information and then later added them to the query duringbuild()
, which is the way it's „supposed“ to work anyways, I guess.I don't think that's likely to ever come (and certainly only between major versions). It would be a UI nightmare and, unless I'm totally mistaken, all possible logic operations can be expressed (albeit with some redundancy) with ANDed ORs (or ORed ANDs) anyways.
Comment #18
drunken monkeyThat one is better, as it correctly adds conditions/filters without a group directly to the query (important, e.g., for argument handlers).
Comment #19
Anonymous (not verified) CreditAttribution: Anonymous commentedYes it works for me (#18), your approach is much "cleaner".
Many thanks for this.
Comment #20
drunken monkeyGreat, committed.
Comment #22
Sebastian.Buesing CreditAttribution: Sebastian.Buesing commentedNow, while this patch may fix what it does it seems that the way SearchApiViewsQuery handles filtering could use some extra work.
This worked well before:
now I have to change it to:
if I want the extra filter to be passed down to the SearchAPI Query. I don't think I should have to call build() here again, should I or shouldn't I add a filter at that point?
Comment #23
zambrey CreditAttribution: zambrey commentedCan grouping be used with fulltext search?
For example I have two exposed filters - one is fulltext search and the other is sku (from commerce). I defined OR group but cannot make it to work when both filters are applied.
It works ok when searching on other fields like title and body.
Comment #24
legolasboThis issue has not seen activity in over 2,5 years. I am therefore closing this issue to clean up the issue queue. Feel free to re-open and update this issue if you feel this issue is still relevant and of importance.