The ease of filtering for MongoDB can be easily achieved as follows:
Item::all(array('conditions' => array('myfield' => array( '$nin' => array(1,2,3) )) ));
If this is what you are doing, you can even create a custom search for it:
class MyModel extends \lithium\data\Model { public static function __init() { parent::__init(); static::finder('notin', function($self, $params, $chain) { // Take all array keys that are not option keys $array = array_diff_key($params['options'], array_fill_keys(array('conditions', 'fields','order','limit','page'),0)); // Clean up options leaving only what li3 expects $params['options'] = array_diff_key($params['options'], $array); $params['options']['conditions'] = array( 'myfield' => array( '$nin' => $array ) ); return $chain->next($self, $params, $chain); }); } }
And name it as follows:
MyModel::notin(array(1,2,3));
In the same way, you can create a custom search for MySQL sources.
As you probably see, this creates some problems if you pass something like array('fields'=>$array) as it will overwrite this option. What happens is that ::notin() (search engines in general) has clear behavior for the (array, null) signature. If this happens, he considers that the first array is the parameters, and the crawler did not accept the arguments. Using notin($array,array()) interrupts the previous search because the first argument ends in $params['notin'] when the real second argument (parameters) is passed.
If you mix data sources on the fly here, I would create a custom model that does not inherit \ lithium \ data \ Model and does not delegate it
to different models and create conditions based on the data source of the final models.
class MyFacadeModel { public static function byNotIn($conditions, $source) { return ($source == "mongodb") ? $source::find( $rewrittenConditions) : $source::find( $rewrittenConditionsForMysql ); } }
(The code may be a little wrong, as it is mostly extracted from the top of the head)