Простая фильтрация для MongoDB может быть легко достигнута следующим образом:
Item::all(array('conditions' =>
array('myfield' => array(
'$nin' => array(1,2,3)
))
));
Если это то, что вы делаете много, вы можете даже создать для него специальный искатель:
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);
});
}
}
И назовите это так:
MyModel::notin(array(1,2,3));
Таким же образом вы можете создать собственный искатель для источников MySQL.
Как вы, вероятно, видите, это создает некоторые проблемы, если вы передаете что-то вроде array('fields'=>$array)
, поскольку это перезаписывает опцию.Что происходит, так это то, что ::notin()
(искатели в общем) имеет отличное поведение для (массива, нулевой) сигнатуры.Если это произойдет, он думает, что первый массив - это параметры, а искатель не принял аргументов.Использование notin($array,array())
разрушает предыдущий искатель, поскольку первый аргумент заканчивается передачей $params['notin']
, когда передается реальный второй аргумент (опции).
Если вы смешиваете источники данных на лету, я бы создал собственную модельон не наследует \ lithium \ data \ Model и разрешает делегировать
различным моделям и создавать условия на основе источника данных конечных моделей.
class MyFacadeModel {
public static function byNotIn($conditions, $source) {
return ($source == "mongodb")
? $source::find( $rewrittenConditions)
: $source::find( $rewrittenConditionsForMysql );
}
}
(Код может быть немного неправильным, так как он в основном берется из головы)