Ich habe eine PHP-Version des MONGODB-Syntaxparsers geschrieben, die über eine SQL-ähnliche Syntax abgefragt werden kann. Ich weiß nicht, ob sie jemand braucht, also teilen Sie sie bitte mit.

WBOY
Freigeben: 2016-08-08 09:31:55
Original
1365 Leute haben es durchsucht

转载请注明作者:wetouns

在使用MONGODB的时候写查询语句总是一件让人蛋疼的事情,如果查询复杂一点,要嵌套好多层对象,于是我就想,能不能使用类似SQL的语法来进行查询呢,这样子代码看起来更加易懂,书写也更为简单,于是就花了些时间把这个想法变为现实该解析器会将类似SQL的语法转换成MONGODB的查询对象,目前条件判断只支持and和or,以及>,<,>=,<=,=的查询,还支持括号表示判断的优先级哦,更多的暂时不支持,想扩展的可以自己改源码,简单说明一下语法和用法吧

例1,我要查询a=0的文档

$query = new MongoQueryParser();
$query->query("a=0");
$queryRst = $query->result;<br>最终$queryRst的结果将会如下图
<p><img alt="" src="http://image.codes51.com/Article/image/20150101/20150101160034_8499.png"><br></p>
<p>例2:</p>
<p>这回来个复杂点的</p>
<pre code_snippet_id="569418" snippet_file_name="blog_20150101_2_7195815" name="code">$query = new MongoQueryParser();
$query->query("a=0 && b > 2");
$queryRst = $query->result;
Nach dem Login kopieren
结果如下


例3:

再来个更复杂的

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

看完以上3个例子,相信不用说明用法,应该也会用了吧,嘿嘿,废话少说,贴上解析器的源码

<?php
class MongoQueryParser {
	function __construct() {
		$this->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;
	}
}

?>
Nach dem Login kopieren

好了,就这么多内容,我想应该会有人需要的
有什么问题直接留言吧

以上就介绍了写了一个PHP版本的MONGODB语法解析器,可以通过类似SQL的语法来进行查询,不知道有人需要不,分享一下吧,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage