Monday, October 05, 2009

Adding negative filters to eZ Find

I've been doing some work with eZ Find recently and have come across an issue that has also troubled others. While eZ Find includes some powerful filtering options there's no support for negative filters.

This can easily remedied by adding "NOT" as an allowed Boolean Operator and adding specific handling of NOT to the final query construction to ezfind/classes/ezfezpsolrquerybuilder.php. This small change allows NOT to be used in the same manor as the existing AND and OR operators.

An enhancement request has been lodged that includes the following patch.

diff --git a/classes/ezfezpsolrquerybuilder.php b/classes/ezfezpsolrquerybuilder.php
index 3c997dc..f30813c 100755
--- a/classes/ezfezpsolrquerybuilder.php
+++ b/classes/ezfezpsolrquerybuilder.php
@@ -852,7 +852,10 @@ class ezfeZPSolrQueryBuilder
}
}

- return implode( " $booleanOperator ", $filterQueryList );
+ if ( $booleanOperator == 'NOT' )
+ return ' NOT ( ' . implode( " OR ", $filterQueryList ) .')';
+ else
+ return implode( " $booleanOperator ", $filterQueryList );
}

/**
@@ -1590,5 +1593,7 @@ ezfeZPSolrQueryBuilder::$FindINI = eZINI::instance( 'ezfind.ini' );
ezfeZPSolrQueryBuilder::$allowedBooleanOperators = array( 'AND',
'and',
'OR',
- 'or' );
+ 'or',
+ 'NOT',
+ 'not' );
?>

To fetch results where the myattr attribute of myclass is not equal to 0 you can write:
{def $results = fetch('ezfind', 'search', hash(
'query', $query,
'filter', array('not', 'myclass/myattr:0')
))}

This query will return any content that where myclass/myattr != 0. This will include objects from other classes, so to limit the results to object of myclass you need to add a class_id filter:
{def $results = fetch('ezfind', 'search', hash(
'query', $query,
'filter', array('not', 'myclass/myattr:0'),
'class_id', 'myclass')
))}

Great to see the documentation for eZ Find 2.1 make it into HTML format!

No comments:

Post a Comment