管道操作 $lookup 可以把两个表进行关联查询,其效果等于mysql的 INNER JOIN 左右两个表必须同时存在的数据。
$lookup有两种方式
第一种,只能使用一个固定的字段关联表,建议这个字段最好是from表的主键,否则效率会很差。
$pipeline[]=['$lookup'=>['from'=>'user_status','localField'=>'user_id','foreignField'=>'_id','as'=>'info']];
第二种,
$pipeline[]=['$lookup'=>['from'=>'user_status','let'=>['type'=>'$type','t1'=>'$t1'],'as'=>'info',
'pipeline'=>[
['$match'=>['day'=>$day_num,
'$expr'=>['$and'=>[
['$eq'=>['$type','$$type']],
['$eq'=>['$t1','$$t1']]]],
'u_id'=>['$gt'=>0],'old'=>0]],
['$project'=>['_id'=>0,'t2'=>1,'val'=>1]],
['$group'=>['_id'=>'$t2','val'=>['$sum' =>'$val']]]
]]];
使用let方法传递了两个参数,同时使用 pipeline 方法对$table表进行操作。
传递的参数必须要使用$$开头才能使用,而且必须要放在 $expr下才可以使用,日过就一个参数$and是可以不用的。pipeline理论上可以使用所有的支持的方法,这中方法相当于在关联之前先对form表进行筛选数据。这种方式在一定情况下是很有使用价值的。
通过以上两种方式 就会在主表中增加info列,格式是顺序数组。
如果你想继续对这个顺序数组进行循环筛选可以使用 $filter 方法。
$pipeline[]=['$project'=>['_id'=>0,'days'=>1,dat=>
['$filter'=>[
'input'=>'$info','as'=>'item',
'cond'=>['$and'=>[['$eq'=>['$$item.country',$country]],['$eq'=>['$$item.com_type',$com_type]]]]
]]]]
在这里 $$item.country是顺序数组info下的字段,$country是主表的字段。同样$and非必须。
这种方式效率上可定不如 $lookup第二种方式效率高,非不得已尽量不用。
如果你直接使用$info.0.country也是可以访问到数据的,但种方式只能在 $match下使用。也就是只能做筛选排除用,在$project下$info.0.country是取不到数据的。
如果要让$info这一列的顺序数组中的每一行都和主表组合成一行新数据就使用$unwind
$pipeline[]=['$unwind'=>['path'=>'$info']];
结果就是新产生的行就中 $info.country 就可以使用了。
后续的操作
$cmd=["aggregate" => $table,'pipeline'=>$pipeline,'cursor' => new \stdClass()];
$command = new Command($cmd);
$this->manager()->executeCommand($table, $command)->toArray();
网上关于php7使用mongodb的资料太少,具体实例更少,很多时候都是官方文档看明白了。但是不会写对应的php代码。这些都是亲身体验后的总结,希望能对以后的人有用。