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