2

我写的,我有一个很难转换到PHP代码的MongoDB查询:转换MongoDB的外壳查询地图和聚合到PHP

var geoips = db.geoip.find().map(function(like){ return like.ip; }); 

var result = db.audit.aggregate([ 
    { $match: { ip: { $nin: geoips } } }, 
    { $group: { 
     _id: "$ip", 
     count: { $sum: 1 } 
    }} 
]); 

UPDATE:

以上查询是下面的关系数据库查询

Select ip,count(*) 
from audit 
where ip not in (select ip from geoip) 
group by ip 

因为我不得不做出MongoDB中3.0版这个查询的等价,我无法利用$ L的ookup在答案中建议。

下面的PHP代码实现了上述目标,并按预期工作。它从geoip集合中获得独特的ips。它传递该结果并在审计集合上执行一个聚合以获得所需的结果。

$geoipcolln = $this->dbConn->selectCollection('geoip');  
$geoips = $geoipcolln->distinct('ip');   
$match = array('ip' => array('$nin' => $geoips));   
$result = $this->collection->aggregate(     
       array(
         '$match' => $match 
        ), 
       array('$group' => array(
          '_id'  => '$ip',         
          'count'  => array('$sum' => 1.0),        
         ))  
      ); 

回答

1

这可以在一个聚合查询中使用$lookup运营商进行如下:

var result = db.audit.aggregate([ 
    { 
     "$lookup": { 
      "from": "geoip", 
      "localField": "ip", 
      "foreignField": "ip", 
      "as": "geoips" 
     } 
    }, 
    { "$match": { "geoips.0": { "$exists": false } } }, 
    { "$group": { 
     "_id": "$ip", 
     "count": { "$sum": 1 } 
    }} 
]) 

然后可以转换为PHP为:

<?php 
    $m = new MongoClient("localhost"); 
    $c = $m->selectDB("yourDB")->selectCollection("audit"); 
    $ops = array(
     array(
      "$lookup" => array(
       "from" => "geoip", 
       "localField" => "ip", 
       "foreignField" => "ip", 
       "as" => "geoips" 
      ) 
     ), 
     array("$match" => array("geoips.0" => array("$exists" => false))), 
     array("$group" => array(
      "_id" => "$ip", 
      "count" => array("$sum" => 1) 
     ))  
    ); 
    $results = $c->aggregate($ops); 
    var_dump($results); 
?> 
+0

这看起来像一个从性能角度来看,这是一个很好的选择但是,我目前运行mongodb 3.0版本。看起来像$ lookup需要3.2版本。此时,我将无法升级。 – FoxShrill