GVKun编程网logo

PHP/MySQL - JSON 中的嵌套组(php解析嵌套json)

11

本文将带您了解关于PHP/MySQL-JSON中的嵌套组的新内容,同时我们还将为您解释php解析嵌套json的相关知识,另外,我们还将为您提供关于Angular4–如何访问模板中的嵌套组件?、MYSQ

本文将带您了解关于PHP/MySQL - JSON 中的嵌套组的新内容,同时我们还将为您解释php解析嵌套json的相关知识,另外,我们还将为您提供关于Angular 4 – 如何访问模板中的嵌套组件?、MYSQL 5.7中的本机JSON支持:MYSQL中JSON数据类型的优缺点是什么?、mysql5.6 解析JSON字符串方式(支持复杂的嵌套格式)、MySQL中的MySQL到JSON的实用信息。

本文目录一览:

PHP/MySQL - JSON 中的嵌套组(php解析嵌套json)

PHP/MySQL - JSON 中的嵌套组(php解析嵌套json)

如何解决PHP/MySQL - JSON 中的嵌套组?

我正在 JSON 中创建嵌套(分层)组。结构很简单 - grand parent -> parent -> child:

main
  secondary
    mcondition

到目前为止,这是使用以下 MysqL/PHP 格式 main -> mcondition

我应该如何更改它以在 main 和 mcondition 之间添加第二级(“次要”,例如父级)?

次要的列是mcondition.secondary

$query = ''SELECT * FROM mcondition ORDER BY mcondition.main ASC'';
$result = $connection->query( $query );

$results = array();
$temp = array();

while ($line = MysqLi_fetch_array($result)) {
    $results[] = $line;
}

foreach($results as $row) {
    $temp[$row[''main'']][''text''] =  $row[''main''];
  if(!isset($temp[$row[''main'']][''children''])) {
      $temp[$row[''main'']][''children''] = array();
  }
  array_push($temp[$row[''main'']][''children''],array(
    ''id'' => $row[''mcondition_pk''],''text'' => $row[''mcondition_name''] 
  ));
}

$temp = array_values($temp);
echo json_encode($temp);

这是 JSON 当前的样子:

[
  {
    "text": "Main heading 1","children": [
      {
        "id": "1","text": "mcondition_1"
      },{
        "id": "17","text": "mcondition_4"
      }
    ]
  },{
    "text": "Main heading 2","children": [
      {
        "id": "49","text": "mcondition_2"
      },{
        "id": "48","text": "mcondition_5"
      }
    ]
  },{
    "text": "Main heading 3","children": [
      {
        "id": "68","text": "mcondition_3"
      },{
        "id": "67","text": "mcondition_6"
      }
    ]
  }
]

这是mcondition表的结构:

    +---------------+------------+------+-----------+
    | mcondition_pk | mcondition | main | secondary |
    +---------------+------------+------+-----------+

mcondition 是唯一的。

解决方法

我仍然不能 100% 确定您预期的 json 会是什么样子,但是您应该能够执行这样的操作。您可能需要进行一些修改才能获得所需的内容。我正在使用数组 $results 来模拟从数据库中获取数据。这将为您提供一个嵌套的层次结构。

$out = [];

$results = [
    [''main'' => ''mk1'',''secondary'' => ''sk1'',''mcondition_pk'' => 1,''mcondition'' => ''mcondition_1''],[''main'' => ''mk1'',''secondary'' => ''sk2'',''mcondition_pk'' => 2,''mcondition'' => ''mcondition_2''],''mcondition_pk'' => 3,''mcondition'' => ''mcondition_3''],[''main'' => ''mk2'',''secondary'' => ''sk3'',''mcondition_pk'' => 4,''mcondition'' => ''mcondition_4''],''mcondition_pk'' => 5,''mcondition'' => ''mcondition_5''],[''main'' => ''mk3'',''secondary'' => ''sk4'',''mcondition_pk'' => 6,''mcondition'' => ''mcondition_6''],''secondary'' => ''sk5'',''mcondition_pk'' => 7,''mcondition'' => ''mcondition_7''],''mcondition_pk'' => 8,''mcondition'' => ''mcondition_8''],];

foreach($results as $row) {
    
    $mk = $row[''main''];
    $sk = $row[''secondary''];
    $pk = $row[''mcondition_pk''];
    $cond = $row[''mcondition''];
    
    $temp = [''id'' => $pk,''text'' => $cond];
    
    if(!isset($out[$mk])) { $out[$mk] = [''text'' => $mk]; }
    if(!isset($out[$mk][$sk])) { $out[$mk][$sk] = [''text'' => $sk,''children'' => []]; }
    
    $out[$mk][$sk][''children''][] = $temp;
    
}

echo "<pre>"; print_r($out); echo "</pre>"; 

$json = json_encode($out);
echo "<pre>"; print_r($json); echo "</pre>"; exit;

Angular 4 – 如何访问模板中的嵌套组件?

Angular 4 – 如何访问模板中的嵌套组件?

我有一个组件层次结构:

App
|
Child
|
Input

组件“Child”接受来自其父级的模板,如下所示:

<my-child>
    <ng-template>
        <my-input></my-input>
        <span>asdasdas</span>
        <my-input></my-input>
        <my-input></my-input>
    </ng-template>    
</my-child>

正如您在模板中看到的那样,有许多输入组件.现在我想访问< my-input>列表.子组件中的组件.我现在尝试的是使用@ ContentChildren / @ ViewChildren,但它似乎不起作用.子组件的代码:

@Component({
  selector: 'my-child',providers: [],template: `
    <div>
      <ng-template [ngTemplateOutlet]="inputTemplate" #input></ng-template>
    </div>
  `,directives: []
})

export class Child implements OnInit,OnAfterViewInit {

  @ContentChild(TemplateRef) inputTemplate: TemplateRef<any>;

  @ViewChildren(InputComponent) inputComponents : QueryList<InputComponent>;

  constructor() {

  }

  ngAfterViewInit(){
    //THIS SHOULD NOT BE EMPTY
    console.log(this.inputComponents.toArray());
  }
}

请让我知道我做错了什么,以及如何从Child组件中获取InputComponents列表.

也许我不应该在这里使用模板?有没有其他方法可以自定义此控件,仍然可以访问嵌套的InputComponents列表?

如果你想玩它here’s the plunker

解决方法

使用@ContentChildren(InputComponent)代替@ViewChildren()并订阅更改

ngAfterViewInit(){
    //THIS SHOULD NOT BE EMPTY
    this.inputComponents.changes.subscribe(c => console.log(this.inputComponents.toArray()));
    //console.log(this.inputComponents.toArray());
  }

为我工作,但说实话,我不知道自己为什么@ContentChildren()而不是@ViewChildren()正在工作.

Plunker link

MYSQL 5.7中的本机JSON支持:MYSQL中JSON数据类型的优缺点是什么?

MYSQL 5.7中的本机JSON支持:MYSQL中JSON数据类型的优缺点是什么?

如何解决MYSQL 5.7中的本机JSON支持:MYSQL中JSON数据类型的优缺点是什么??

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...

在这样的表达式或函数中使用列会浪费使用索引来帮助优化查询的任何机会。上面显示的查询被强制执行表扫描。

关于“有效访问”的说法具有误导性。这意味着在查询检查了带有JSON文档的行之后,它可以提取一个字段,而不必解析JSON语法的文本。但是仍然需要进行表格扫描来搜索行。换句话说,查询必须检查每一行。

以此类推,如果我在电话簿中搜索名字为“比尔”的人,即使我的名字被突出显示以使其更快地发现它们,我仍然必须阅读电话簿中的每一页。

MysqL 5.7允许您在表中定义虚拟列,然后在虚拟列上创建索引。

ALTER TABLE t1
  ADD COLUMN series AS (JSON_EXTRACT(data, ''$.series'')),
  ADD INDEX (series);

然后,如果您查询虚拟列,它可以使用索引并避免进行表扫描。

SELECT * FROM t1
WHERE series IN ...

很好,但是有点遗漏了使用JSON的意义。使用JSON的吸引力在于,它允许您添加新属性,而无需执行ALTER TABLE。但是事实证明,如果要在索引的帮助下搜索JSON字段,则无论如何都必须定义一个额外的(虚拟)列。

但是,您不必为JSON文档中的 每个 字段定义虚拟列和索引,而只需定义要搜索或排序的列和索引。JSON中可能还有其他属性,您只需要将它们提取到选择列表中,如下所示:

SELECT JSON_EXTRACT(data, ''$.series'') AS series FROM t1
WHERE <other conditions>

我通常会说这是在MysqL中使用JSON的最佳方法。仅在选择列表中。

当您在其他子句(JOIN,WHERE,GROUP BY,HAVING,ORDER BY)中引用列时,使用常规列而不是JSON文档中的字段会更有效。

我在2018年4月的Percona Live会议上发表了名为“如何在MySQL错误中使用JSON的JSON”的演讲。我将在秋季在Oracle Code One上更新并重复该演讲。

JSON还有其他问题。例如,在我的测试中,JSON文档所需的存储空间是存储相同数据的常规列的2-3倍。

MysqL正在积极地推广其新的JSON功能,主要目的是劝说人们不要迁移到MongoDB。但是像MongoDB这样的面向文档的数据存储从根本上讲是一种非关系式的数据组织方式。它不同于关系型。我并不是说一个比另一个更好,这只是一种不同的技术,适用于不同类型的查询。

当JSON使查询更高效时,您应该选择使用JSON。

编辑:如果您的WHERE子句使用与虚拟列的定义完全相同的表达式,则MysqL中的虚拟列实现应该使用索引。也就是说,以下内容 使用虚拟列上的索引,因为虚拟列已定义AS (JSON_EXTRACT(data,"$.series"))

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...

除非通过测试此功能发现,否则如果表达式是JSON提取函数,由于某种原因它将不起作用。它适用于其他类型的表达式,但不适用于JSON函数。

解决方法

在MySQL
5.7中,添加了用于在JSON表中存储JSON数据的新数据类型。显然,这将是MySQL的巨大变化。他们列出了一些好处

文档验证 -JSON列中只能存储有效的JSON文档,因此您可以自动验证数据。

有效访问
-更重要的是,当您将JSON文档存储在JSON列中时,它不会存储为纯文本值。相反,它以优化的二进制格式存储,从而可以更快地访问对象成员和数组元素。

性能 -通过在JSON列中的值上创建索引来提高查询性能。这可以通过虚拟列上的“功能索引”来实现。

便利性 -JSON列的附加内联语法使在SQL中集成文档查询变得非常自然。例如(features.feature是一个JSON列):SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254;

哇 !它们包括一些很棒的功能。现在,更容易操作数据。现在可以在列中存储更复杂的数据。因此,MySQL现在具有NoSQL的味道。

现在我可以想象对JSON数据的查询类似

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN 
( 
SELECT JSON_EXTRACT(data,"$.inverted") 
FROM t1 | {"series": 3,"inverted": 8} 
WHERE JSON_EXTRACT(data,"$.inverted")<4 );

那我可以在几个json列中存储巨大的小关系吗?好吗?它破坏规范化了吗? 如果可能的话,我想它将像MySQL列中的NoSQL一样
。我真的很想了解更多有关此功能的信息。MySQL JSON数据类型的优缺点。

mysql5.6 解析JSON字符串方式(支持复杂的嵌套格式)

mysql5.6 解析JSON字符串方式(支持复杂的嵌套格式)

mysql5.6 解析JSON字符串

支持复杂的嵌套格式

废话不多说,先上代码。

CREATE FUNCTION `json_parse`(`jsondata` longtext,`keyname` text) RETURNS text CHARSET utf8
BEGIN
	DECLARE delim VARCHAR(128);
	DECLARE	result longtext;
	DECLARE startpos INTEGER;
	DECLARE endpos INTEGER;
	DECLARE endpos1 INTEGER;
  DECLARE findpos INTEGER;
	DECLARE leftbrace INTEGER;
	DECLARE tmp longtext;
  DECLARE tmp2 longtext;
	DECLARE Flag INTEGER;
 
	SET delim = CONCAT(''"'', keyname, ''": "'');
	SET startpos = locate(delim,jsondata);
 
	IF startpos > 0 THEN
		SET findpos = startpos+length(delim);
		SET leftbrace = 1;
		SET endpos = 0;
		SET Flag =1;
		get_token_loop: repeat 
				IF substr(jsondata,findpos,2)=''\\"'' THEN
					SET findpos = findpos + 2;
					iterate get_token_loop;
				ELSEIF substr(jsondata,findpos,2)=''\\\\'' THEN
					SET findpos = findpos + 2;
					iterate get_token_loop;
				ELSEIF substr(jsondata,findpos,1)=''"'' AND Flag = 1  THEN 
						SET endpos = findpos;
						SET findpos = LENGTH(jsondata)+1;
						leave get_token_loop;
				END IF;
				SET findpos = findpos + 1;
			UNTIL findpos > LENGTH(jsondata) END repeat;
			
			IF endpos > 0 THEN
				SELECT 
					substr(
						jsondata
						,startpos
						+length(delim)#取出value值的起始位置
						,endpos#取出value值的结束位置
						-(
							startpos
							+length(delim)
							)#减去value值的起始位置,得到value值字符长度
					) INTO result
				FROM DUAL;
				SET result= replace(result,''\\"'',''"'');
				SET result= replace(result,''\\\\'',''\\'');
			ELSE 
				SET result=null;
			END IF;
				/*
		SELECT 
			substr(
				jsondata
				,locate(delim,jsondata)
				+length(delim)#取出value值的起始位置
				,locate(
					''"''
					,jsondata
					,locate(delim,jsondata)
					+length(delim)
					)#取出value值的结束位置
				-(
					locate(delim,jsondata)
					+length(delim)
					)#减去value值的起始位置,得到value值字符长度
			) INTO result
		FROM DUAL;	*/
	ELSE
			SET delim = CONCAT(''"'', keyname, ''": {'');
			SET startpos = locate(delim,jsondata);
			IF startpos > 0 THEN
				SET findpos = startpos+length(delim);
				SET leftbrace = 0;
				SET endpos = 0;
				SET Flag =0;
	
			get_token_loop: repeat 
					IF substr(jsondata,findpos,2)=''{"'' THEN
						SET leftbrace = leftbrace + 1;
						SET findpos = findpos + 2;
						iterate get_token_loop;
					ELSEIF substr(jsondata,findpos,2)=''\\"'' THEN
						SET findpos = findpos + 2;
						iterate get_token_loop;
					ELSEIF substr(jsondata,findpos,3)='': "'' THEN
							SET Flag = 1;
							SET findpos = findpos + 3;
							iterate get_token_loop;
					ELSEIF substr(jsondata,findpos,1)=''"'' THEN
						SET Flag = 0;
					ELSEIF substr(jsondata,findpos,1)=''}'' AND Flag = 0  THEN
						IF leftbrace > 0 THEN
							SET leftbrace = leftbrace - 1;
						ELSE 
							SET endpos = findpos;
							SET findpos = LENGTH(jsondata)+1;
						END IF;
					END IF;
					SET findpos = findpos + 1;
				UNTIL findpos > LENGTH(jsondata) END repeat;
				
				IF endpos > 0 THEN
					SELECT 
						substr(
							jsondata
							,startpos
							+length(delim)#取出value值的起始位置
							,endpos#取出value值的结束位置
							-(
								startpos
								+length(delim)
								)#减去value值的起始位置,得到value值字符长度
						) INTO result
					FROM DUAL;
					SET result=CONCAT("{",result, ''}'');
				ELSE 
					SET result=null;
				END IF;
			ELSE 
				SET delim = CONCAT(''"'', keyname, ''": ['');
				SET startpos = locate(delim,jsondata);
				IF startpos > 0 THEN
					SET findpos = startpos+length(delim);
					SET leftbrace = 0;
					SET endpos = 0;
 
						SET tmp = substring_index(jsondata,delim,-1);
						SET tmp2 = substring_index(tmp,'']'',1);
						
				   IF locate(''['',tmp2) =0 THEN					
							SET endpos = locate('']'',tmp);
							SET endpos = endpos+findpos-1;
					 ELSE
							get_token_loop: repeat 
									IF substr(jsondata,findpos,2)=''\\"'' THEN
										SET findpos = findpos + 2;
										iterate get_token_loop;
									ELSEIF substr(jsondata,findpos,3)='': "'' THEN
											SET Flag = 1;
											SET findpos = findpos + 3;
											iterate get_token_loop;
									ELSEIF substr(jsondata,findpos,1)=''['' AND Flag = 0 THEN
										SET leftbrace = leftbrace + 1;
										SET findpos = findpos + 1;
										iterate get_token_loop;
									ELSEIF substr(jsondata,findpos,1)=''"'' THEN
										SET Flag = 0;
									ELSEIF substr(jsondata,findpos,1)='']'' AND Flag = 0  THEN
										IF leftbrace > 0 THEN
											SET leftbrace = leftbrace - 1;
										ELSE 
											SET endpos = findpos;
											SET findpos = LENGTH(jsondata)+1;
										END IF;
									END IF;
									SET findpos = findpos + 1;
								UNTIL findpos > LENGTH(jsondata) END repeat;
					END IF;
					IF endpos > 0 THEN
						SELECT 
							substr(
								jsondata
								,startpos
								+length(delim)#取出value值的起始位置
								,endpos#取出value值的结束位置
								-(
									locate(delim,jsondata)
									+length(delim)
									)#减去value值的起始位置,得到value值字符长度
							) INTO result
						FROM DUAL;
						SET result=CONCAT("[",result, '']'');
					ELSE 
						SET result=null;
					END IF;
				ELSE 					
					SET delim = CONCAT(''"'', keyname, ''": '');
					SET startpos = locate(delim,jsondata);
					IF startpos > 0 THEN
						SET endpos = locate('','',jsondata,startpos+length(delim));
						SET endpos1 = locate(''}'',jsondata,startpos+length(delim));
						IF endpos>0 OR endpos1>0 THEN
								IF endpos1>0 AND endpos1 < endpos OR endpos =0 THEN
									SET endpos = endpos1;
								END IF;
								SELECT 
									substr(
										jsondata
										,startpos
										+length(delim)#取出value值的起始位置
										,endpos#取出value值的结束位置
										-(
											locate(delim,jsondata)
											+length(delim)
											)#减去value值的起始位置,得到value值字符长度
									) INTO result
								FROM DUAL;
								
								IF STRCMP(result,''null'')=0 THEN
									SET result=null;
								END IF;
						ELSE 					
							SET result=null;
						END IF;
					ELSE 					
						SET result=null;
					END IF;
				END IF;
			END IF;
	END IF;
	if result='''' and RIGHT(keyname,2)=''Id'' then
		SET result=null;
	end if;
	RETURN result;
END

jsondata需要严格的json格式(注意逗号和分号以及双引号之间的空格)

SET jsondata=''{"CurrentPage": 1, "data": [{"config": "123"}, {"config": "456"}], "PageSize": 10}'' 
SELECT json_parse(jsondata, ''CurrentPage'') INTO CurrentPage;
SELECT json_parse(jsondata, ''data'') INTO data;

这边如果想获取config的内容,可以这样处理

        SET count = (LENGTH(data)-LENGTH(REPLACE(data,''},'','''')))/2+1;
        SET i = 0;
        WHILE i < count DO
            SET SetObject = SUBSTRING_INDEX(SUBSTRING_INDEX(data,''},'',i+1),''},'',-1);
            IF LENGTH(SetObject)>0 THEN
                SELECT json_parse(SetObject, ''config'') INTO config;    
            END IF;
            SET i = i + 1;
        END WHILE;

不足之处,jsondata数据多的情况下,会有效率问题。

mysql5.6及以下解析json方法

之前在公司发现在线的查询平台是MySQL5.6,不能用JSON_EXTRACT,也不能用存储过程,所以只能自己编了一个简单的小查询,几条数据还是能查的,如果数据量大的话,估计耗的资源就会比较多。

先说一下问题的背景

是想在''{"platform":"Android","source":"tt","details":null}''这一串东西里面找到source这个key对应的value值。

这个方法是先找到source":"这个字符串的起始位置和长度,这样就能够找到value值的起始位置;再找到这个字符串以后第一个"出现的位置,就能得到value值的结束位置。

再利用substr函数,就可以取出对应的位置。

下面是对应的代码 

SELECT 
''{"platform":"Android","source":"tt","details":null}'' as ''sample''
,substr(
  ''{"platform":"Android","source":"tt","details":null}''
  ,locate(''source":"'',''{"platform":"Android","source":"tt","details":null}'')
   +length(''source":"'')#取出value值的起始位置
  ,locate(
  		''"''
  		,''{"platform":"Android","source":"tt","details":null}''
  		,locate(''source":"'',''{"platform":"Android","source":"tt","details":null}'')
  		+length(''source":"'')
  		)#取出value值的结束位置
	  -(
	  	locate(''source":"'',''{"platform":"Android","source":"tt","details":null}'')
	  	+length(''source":"'')
	  	)#减去value值的起始位置,得到value值字符长度
  ) as result
FROM DUAL 

运行以后,就得到result的结果,就是tt。如果需要其他元素,就替换一下对应的key值和字段,就好了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。 

您可能感兴趣的文章:
  • mysql全面解析json/数组
  • Mysql如何对json数据进行查询及修改
  • mysql中取出json字段的小技巧
  • MySQL更新存放JSON的字段、\“ 转义成 “的问题描述

MySQL中的MySQL到JSON

MySQL中的MySQL到JSON

我有一个基本的MySQL数据库表人3列(ID,名称,距离)

我试图用PHP作为JSON输出这个,所以我的网络应用程序可以拿起它.我尝试使用另一个答案的解决方案:

$sth = MysqL_query($con,"SELECT * FROM People");
$rows = array();
while($r = MysqL_fetch_assoc($sth)) {
    $rows[] = $r;
}
print json_encode($rows);

但是我只是返回一个空白数组[].

更新:更改为MysqLi并添加了转储:

$sth = MysqLi_query("SELECT * FROM Events",$con);
$rows = array();
var_dump($sth);
while($r = MysqLi_fetch_assoc($sth)) {
var_dump($rows); 
$rows[] = $r;
}
print json_encode($rows);

返回:

空值 []

解决方法:

在MysqL_query语句中交换查询和连接:

$sth = MysqL_query("SELECT * FROM People", $con);

除此之外,不推荐使用MysqL-library.如果您正在编写新代码,请考虑使用MysqLi_或PDO.

今天关于PHP/MySQL - JSON 中的嵌套组php解析嵌套json的分享就到这里,希望大家有所收获,若想了解更多关于Angular 4 – 如何访问模板中的嵌套组件?、MYSQL 5.7中的本机JSON支持:MYSQL中JSON数据类型的优缺点是什么?、mysql5.6 解析JSON字符串方式(支持复杂的嵌套格式)、MySQL中的MySQL到JSON等相关知识,可以在本站进行查询。

本文标签: