ホームページ バックエンド開発 PHPチュートリアル SQL に似た構文でクエリできる PHP バージョンの MONGODB 構文パーサーを作成しました。必要な人がいるかどうかわかりませんので、共有してください。

SQL に似た構文でクエリできる PHP バージョンの MONGODB 構文パーサーを作成しました。必要な人がいるかどうかわかりませんので、共有してください。

Aug 08, 2016 am 09:31 AM
gt query quot this

转载请注明作者:wetouns

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

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

$query = new MongoQueryParser();
$query-&gt;query("a=0");
$queryRst = $query-&gt;result;<br>最终$queryRst的结果将会如下图
<p><img src="/static/imghw/default1.png" data-src="http://image.codes51.com/Article/image/20150101/20150101160034_8499.png" class="lazy" alt=""><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-&gt;query("a=0 &amp;&amp; b &gt; 2");
$queryRst = $query-&gt;result;
ログイン後にコピー
结果如下


例3:

再来个更复杂的

$query = new MongoQueryParser();
$query-&gt;query("(a=0 &amp;&amp; b &gt; 2) || c &lt;= 5&quot;);
$queryRst = $query-&gt;result;
ログイン後にコピー
结果如下

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

&lt;?php
class MongoQueryParser {
	function __construct() {
		$this-&gt;result =[];
	}
	
	public $result;
	
	public $leftFirstReg = "/\\(([^\\s]+)\\)(&amp;&amp;|\\|\\|)([^\\s]+$)/";//匹配左括号优先
	public $rightFirstReg = "/([^\\s]+?)(&amp;&amp;|\\|\\|)\\(([^\\s]+)\\)$/";//右括号优先
	public $allReg = "/\\(([^\\s]+)\\)(&amp;&amp;|\\|\\|)\\(([^\\s]+)\\)$/";//左右括号模式
	public $reg1 = "/([^\\s]+)(&amp;&amp;|\\|\\|)([^\\s]+)/";
	public $reg2 = "/([\\w]+)([=&lt;&gt;]+)([^\\s]+)/";
	public $opMap = ["&gt;"=&gt;'$gt',"&lt;&quot;=&gt;'$lt',"&gt;="=&gt;'$gte',"&lt;=&quot;=&gt;'$lte'];
	private $meetOr = false;
	
	/**
	 * 将自定义的查询语句转换成MONGODB的查询语句
	 * 例1:a=3
	 * 例2:a&gt;0&amp;&amp;a&lt;2
	 * 例3:a&gt;0&amp;&amp;a&lt;2||c&gt;3
	 */
	function query($query){
		$query =preg_replace("/\s/","",$query);
		$this-&gt;result = $this-&gt;exec($query,false,false);
		return $this-&gt;result;
	}
		
	function exec($query,$layer,$fromAnd){
		if(preg_match($this-&gt;allReg, $query,$matches1) &gt; 0 || 
			preg_match($this-&gt;rightFirstReg, $query,$matches2) &gt; 0 ||
			preg_match($this-&gt;leftFirstReg, $query,$matches3) &gt; 0 || 
			preg_match($this-&gt;reg1, $query,$matches4)){
			$mat = null;
			$leftSame = false;
			$rightSame = false;
			if(count($matches1) &gt; 0){
				$mat = $matches1;
			}else if(count($matches2) &gt; 0){
				$leftSame = true;
				$rightSame = false;
				$mat = $matches2;
			}else if(count($matches3) &gt; 0){
				$leftSame = false;
				$rightSame = true;
				$mat = $matches3;
			}else if(count($matches4) &gt; 0){
				$leftSame = true;
				$rightSame = true;
				$mat = $matches4;
			}
			
			$op = $mat[2];
			$left = $mat[1];
			$right = $mat[3];
			
			if($op == "&amp;&amp;"){//如果操作符是AND
				$rst = null;
				if(!$layer || !$fromAnd){//如果不同层,或者调用来自上一层的or,那么就建立一个$and操作符
					$rst['$and'] = [];
					$larr = $this-&gt;exec($mat[1],$leftSame,true);
					$rarr = $this-&gt;exec($mat[3],$rightSame,true);
					$rst['$and'] = $this-&gt;mergeArr($rst['$and'],$larr, $rarr);
					return $rst;
				}else{//如果同层,直接把值都放到同层数组去
					$rst = array_merge($this-&gt;exec($mat[1],$leftSame,true),$this-&gt;exec($mat[3],$rightSame,true));
					return $rst;
				}
			}else if($op == "||"){
				if(!$layer || $fromAnd){//如果不同层
					$rst['$or'] = [];
					$larr = $this-&gt;exec($mat[1],$leftSame,false);
					$rarr = $this-&gt;exec($mat[3],$rightSame,false);
					$rst['$or'] = $this-&gt;mergeArr($rst['$or'],$larr, $rarr);
				}else{
					$rst = [];
					$rst = array_merge($this-&gt;exec($mat[1],$leftSame,false),$this-&gt;exec($mat[3],$rightSame,false));
				}
				return $rst;
			}
		}
		else{//如果最终已经分解成a=b的形式时,就在此解析
			preg_match($this-&gt;reg2, $query,$matches);
			if(count($matches) &gt;= 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-&gt;opMap[$op]] = (float)$right;
					}else{
						$rst[$left][$this-&gt;opMap[$op]] = $right;
					}
				}
				return $rst;
			}
		}
	}
	
	function mergeArr($rst,$larr,$rarr){
		foreach ($larr as $lk=&gt;$lv){
			$lcond = [];
			$lcond[$lk] = $lv;
			$rst[] = $lcond;
		}
			
		foreach ($rarr as $rk=&gt;$rv){
			$rcond = [];
			$rcond[$rk] = $rv;
			$rst[] = $rcond;
		}
		return $rst;
	}
}

?&gt;
ログイン後にコピー

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

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

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Huawei GT3 ProとGT4の違いは何ですか? Huawei GT3 ProとGT4の違いは何ですか? Dec 29, 2023 pm 02:27 PM

Huawei GT3 ProとGT4の違いは何ですか?

修正: Windows 11 で Snipping ツールが機能しない 修正: Windows 11 で Snipping ツールが機能しない Aug 24, 2023 am 09:48 AM

修正: Windows 11 で Snipping ツールが機能しない

Power Query で複数の列をドラッグ アンド ドロップで並べ替える方法 Power Query で複数の列をドラッグ アンド ドロップで並べ替える方法 Mar 14, 2024 am 10:55 AM

Power Query で複数の列をドラッグ アンド ドロップで並べ替える方法

iPhoneでApp Storeに接続できないエラーを修正する方法 iPhoneでApp Storeに接続できないエラーを修正する方法 Jul 29, 2023 am 08:22 AM

iPhoneでApp Storeに接続できないエラーを修正する方法

React Query データベース プラグイン: データをインポートおよびエクスポートする方法 React Query データベース プラグイン: データをインポートおよびエクスポートする方法 Sep 26, 2023 pm 05:37 PM

React Query データベース プラグイン: データをインポートおよびエクスポートする方法

Power Query を使用してデータを NTFS に分割する方法 Power Query を使用してデータを NTFS に分割する方法 Mar 15, 2024 am 11:00 AM

Power Query を使用してデータを NTFS に分割する方法

php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决 Jun 13, 2016 am 10:23 AM

php提交表单通过后,弹出的对话框怎样在当前页弹出,该如何解决

watch4proとGTのどちらが優れていますか? watch4proとGTのどちらが優れていますか? Sep 26, 2023 pm 02:45 PM

watch4proとGTのどちらが優れていますか?

See all articles