寫了一個PHP版本的MONGODB文法解析器,可以通過類似SQL的文法來進行查詢,不知道有人需要不,分享一下吧

來源:互聯網
上載者:User
轉載請註明作者:wetouns

在使用MONGODB的時候寫查詢語句總是一件讓人蛋疼的事情,如果查詢複雜一點,要嵌套好多層對象,於是我就想,能不能使用類似SQL的文法來進行查詢呢,這樣子代碼看起來更加易懂,書寫也更為簡單,於是就花了些時間把這個想法變為現實該解析器會將類似SQL的文法轉換成MONGODB的查詢對象,目前條件判斷只支援and和or,以及>,<,>=,<=,=的查詢,還支援括弧表示判斷的優先順序哦,更多的暫時不支援,想擴充的可以自己改源碼,簡單說明一下文法和用法吧

例1,我要查詢a=0的文檔

$query = new MongoQueryParser();$query->query("a=0");$queryRst = $query->result;

最終$queryRst的結果將會如


例2:

這回來個複雜點的

$query = new MongoQueryParser();$query->query("a=0 && b > 2");$queryRst = $query->result;
結果如下


例3:

再來個更複雜的

$query = new MongoQueryParser();$query->query("(a=0 && b > 2) || c <= 5");$queryRst = $query->result;
結果如下

看完以上3個例子,相信不用說明用法,應該也會用了吧,嘿嘿,廢話少說,貼上解析器的源碼

result =[];}public $result;public $leftFirstReg = "/\\(([^\\s]+)\\)(&&|\\|\\|)([^\\s]+$)/";//匹配左括弧優先public $rightFirstReg = "/([^\\s]+?)(&&|\\|\\|)\\(([^\\s]+)\\)$/";//右括弧優先public $allReg = "/\\(([^\\s]+)\\)(&&|\\|\\|)\\(([^\\s]+)\\)$/";//左右括弧模式public $reg1 = "/([^\\s]+)(&&|\\|\\|)([^\\s]+)/";public $reg2 = "/([\\w]+)([=<>]+)([^\\s]+)/";public $opMap = [">"=>'$gt',"<"=>'$lt',">="=>'$gte',"<="=>'$lte'];private $meetOr = false;/** * 將自訂的查詢語句轉換成MONGODB的查詢語句 * 例1:a=3 * 例2:a>0&&a<2 * 例3:a>0&&a<2||c>3 */function query($query){$query =preg_replace("/\s/","",$query);$this->result = $this->exec($query,false,false);return $this->result;}function exec($query,$layer,$fromAnd){if(preg_match($this->allReg, $query,$matches1) > 0 || preg_match($this->rightFirstReg, $query,$matches2) > 0 ||preg_match($this->leftFirstReg, $query,$matches3) > 0 || preg_match($this->reg1, $query,$matches4)){$mat = null;$leftSame = false;$rightSame = false;if(count($matches1) > 0){$mat = $matches1;}else if(count($matches2) > 0){$leftSame = true;$rightSame = false;$mat = $matches2;}else if(count($matches3) > 0){$leftSame = false;$rightSame = true;$mat = $matches3;}else if(count($matches4) > 0){$leftSame = true;$rightSame = true;$mat = $matches4;}$op = $mat[2];$left = $mat[1];$right = $mat[3];if($op == "&&"){//如果操作符是AND$rst = null;if(!$layer || !$fromAnd){//如果不同層,或者調用來自上一層的or,那麼就建立一個$and操作符$rst['$and'] = [];$larr = $this->exec($mat[1],$leftSame,true);$rarr = $this->exec($mat[3],$rightSame,true);$rst['$and'] = $this->mergeArr($rst['$and'],$larr, $rarr);return $rst;}else{//如果同層,直接把值都放到同層數組去$rst = array_merge($this->exec($mat[1],$leftSame,true),$this->exec($mat[3],$rightSame,true));return $rst;}}else if($op == "||"){if(!$layer || $fromAnd){//如果不同層$rst['$or'] = [];$larr = $this->exec($mat[1],$leftSame,false);$rarr = $this->exec($mat[3],$rightSame,false);$rst['$or'] = $this->mergeArr($rst['$or'],$larr, $rarr);}else{$rst = [];$rst = array_merge($this->exec($mat[1],$leftSame,false),$this->exec($mat[3],$rightSame,false));}return $rst;}}else{//如果最終已經分解成a=b的形式時,就在此解析preg_match($this->reg2, $query,$matches);if(count($matches) >= 4){$left = $matches[1];$op = $matches[2];$right = $matches[3];$rst = [];if($op == "="){if(is_numeric($right)){$rst[$left] = (float)$right;}else{$rst[$left] = $right;}}else{if(!isset($rst[$left])){$rst[$left] = [];}if(is_numeric($right)){$rst[$left][$this->opMap[$op]] = (float)$right;}else{$rst[$left][$this->opMap[$op]] = $right;}}return $rst;}}}function mergeArr($rst,$larr,$rarr){foreach ($larr as $lk=>$lv){$lcond = [];$lcond[$lk] = $lv;$rst[] = $lcond;}foreach ($rarr as $rk=>$rv){$rcond = [];$rcond[$rk] = $rv;$rst[] = $rcond;}return $rst;}}?>

好了,就這麼多內容,我想應該會有人需要的
有什麼問題直接留言吧

以上就介紹了寫了一個PHP版本的MONGODB文法解析器,可以通過類似SQL的文法來進行查詢,不知道有人需要不,分享一下吧,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.