仅对 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()
(通常的查找器)对 (array,null) 签名具有不同的行为。如果发生这种情况,它认为第一个数组是选项并且查找器不接受任何参数。Usingnotin($array,array())
会破坏前一个查找器,因为第一个参数在$params['notin']
传递真正的第二个参数(选项)时结束。
如果您在这里动态混合数据源,我将创建一个不继承 \lithium\data\Model 的自定义模型,并将其委托
给不同的模型并根据最终模型数据源创建条件。
class MyFacadeModel {
public static function byNotIn($conditions, $source) {
return ($source == "mongodb")
? $source::find( $rewrittenConditions)
: $source::find( $rewrittenConditionsForMysql );
}
}
(代码可能有点不正确,因为它主要取自我的头顶)