To implement support for OR facets in the DB backend (#1390586: Add support for OR facets), we need to be able to build a new search query with just the facet filters for a particular facet excluded.

This is currently really hard, because there is no easy way to identify the filters added by a particular facet. The Solr implementation is also affected, as it adds exclusion tags to the Solr query in a "less then pretty" way (it uses a regular expression on the built fq parameter).

I suggest we add a way to associate each filter with some arbitrary tags.

Comments

damien tournoud’s picture

Status: Active » Needs review
StatusFileSize
new4.79 KB

Here is a very simple implementation of this idea.

damien tournoud’s picture

StatusFileSize
new5.3 KB

Re-roll of the same patch, with an additional exception if the operator is unknown.

drunken monkey’s picture

Status: Needs review » Needs work
Issue tags: +API change

Sorry, I've been looking at this patch now and then for well over a month now, but I'm just not sure.
I agree it's a very soft API change (or, rather, addition), but when other modules then rely on this, we introduce yet again some version incompatibilities which are sure to trip some people up.
In any case, we couldn't use this in #1390586: Add support for OR facets until there's a new Search API release with this included. When we wait a bit and mention it prominently enough, we might avoid these problems as far as possible … (Also, at least for Solr, we could leave the alternative also in for a bit, with some code checking for the existence of tags.)

Anyways, I've asked for others to comment, maybe someone has a strong opinion or arguments for either side.
If not, I guess I'll commit this in the coming weeks …
Sorry you had to wait so long, and thank you very much for the initiative and your patches!

On a more technical note (i.e., actual patch review):

+++ b/contrib/search_api_facetapi/plugins/facetapi/query_type_term.inc
@@ -40,24 +40,27 @@ class SearchApiFacetapiTerm extends FacetapiQueryType implements FacetapiQueryTy
+      $conjonction = 'AND';
+    }
+    elseif ($operator == FACETAPI_OPERATOR_OR) {
+      $conjonction = 'OR';
+++ b/contrib/search_api_facetapi/plugins/facetapi/query_type_term.inc
@@ -40,24 +40,27 @@ class SearchApiFacetapiTerm extends FacetapiQueryType implements FacetapiQueryTy
+    $facet_filter = $query->createFilter($conjonction, $tags);

"conjonction"

+++ b/contrib/search_api_facetapi/plugins/facetapi/query_type_term.inc
@@ -40,24 +40,27 @@ class SearchApiFacetapiTerm extends FacetapiQueryType implements FacetapiQueryTy
+      throw new SearchApiException(t('Unknown facet operator %operator.', array('%operator' => $operator)));

Even I would say that this is too cautious. We should be able to rely on the Facet API only passing these two operators here.
On the other hand, it doesn't really hurt and in the future there might even be other operators defined by the Facet API …
I guess either way is fine.

+++ b/includes/query.inc
@@ -965,6 +973,11 @@ interface SearchApiQueryFilterInterface {
+   */
+  public function &getTags();
 }

Newline after the method, please.

+++ b/includes/query.inc
@@ -986,10 +999,15 @@ class SearchApiQueryFilter implements SearchApiQueryFilterInterface {
+  public function __construct($conjunction = 'AND', $tags = array()) {

This and all other instances: Please use type hinting, i.e., array $tags = array().

Also, we should preprocess the tags with drupal_map_assoc() so we can just use isset($tags[$tag]) to check for a certain tag.
There should also be a hasTag($tag) method for doing this directly.

restyler’s picture

Hi guys, I came here from https://drupal.org/node/1390586 ("or" operator issue for db engine)
More than 2 months passed, and since there are no objections, may be we should commit it to dev and wait for some bugreporting? :)

drunken monkey’s picture

Issue summary: View changes
Status: Needs work » Fixed

It's 14 months (now 16), not two. Not really better, though – I have to apologize, it must have slipped from my radar.
I now fixed the few issues mentioned in the last comment and committed the patch.
Thanks again, Damien, and sorry it took me so long!

Status: Fixed » Closed (fixed)

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