从包含KDB中的JSON文本的列中提取多个列

时间:2018-03-12 22:19:55

标签: kdb

我有一个包含JSON文本列的表。我想解析该列并将不同的属性提取到多个列。

c:([] date:2?.z.d ;  client:( "{  \"firstName\": \"John\",  \"lastName\": \"Smith\", \"age\": 27 }" ; "{  \"firstName\": \"Scott\",  \"lastName\": \"Tiger\", \"age\":29 }" ) )  

5 个答案:

答案 0 :(得分:2)

如果你在表格中的每个json上执行.j.k,你将会得到一个类似于表格的词典列表;

q)exec .j.k each client from c
firstName lastName age
----------------------
"John"    "Smith"  27 
"Scott"   "Tiger"  29 

然后,您可以将其加入原始表并提取您喜欢的任何数据;

q)foo:(,'/)(c; exec .j.k each client from c)
q)select date, firstName, lastName, age from foo
date       firstName lastName age
---------------------------------
2008.02.04 "John"    "Smith"  27 
2015.01.02 "Scott"   "Tiger"  29 

答案 1 :(得分:2)

这是从整个json列创建单个json数组的另一种方法。

在单个字符串上运行.j.k比在许多小型数组/字典/字符串上运行.j.k更有效。

// test table
q)c:([] date:2?.z.d ;  client:( "{  \"firstName\": \"John\",  \"lastName\": \"Smith\", \"age\": 27 }" ; "{  \"firstName\": \"Scott\",  \"lastName\": \"Tiger\", \"age\":29 }" ) );
// combine each string with "," and encompass in "[]"
// join each parsed dictionary with each row from c, keep client column for keep sake
q)c,'exec .j.k {"[",x,"]"}"," sv client from c

json捕获的情况通常是数据和消息是无模式/非结构化的。如果是这种情况,并且每个json字符串不一定与其他字符串具有相同的标记,那么您可以创建所需输出的静态映射,并将该映射连接到每个已解析的json消息。这将具有始终解析为表的影响。您还可以键入地图以确保正确键入结果表。

// insert row with missing age tag and new location tag
q)`c insert (.z.d;"{\"firstName\": \"Sean\", \"lastName\": \"O'Hagan\", \"location\" : \"Dub\"}");
// name and locations are strings, age is float
q)map:{x,'first each x$\:()}[`firstName`lastName`age`location!10 10 9 11h];
// manually edit symbol nulls to be varchars, so when casting to symbol the RHS param is always a varchar
q).[`map;where map[;1]~\:`;:;(-11h;" ")];
// join map to each parsed dictionary, and delete client column as we have extracted useful data
q)delete client from c,'exec flip map[;0]$flip (map[;1],/:.j.k {"[",x,"]"}"," sv client) from c
date       firstName lastName  age location
-------------------------------------------
2004.02.01 "John"    "Smith"   27
2005.06.06 "Scott"   "Tiger"   29
2018.03.13 "Sean"    "O'Hagan"     Dub
q)meta delete client from c,'exec flip map[;0]$flip (map[;1],/:.j.k {"[",x,"]"}"," sv client) from c
c        | t f a
---------| -----
date     | d
firstName| C
lastName | C
age      | f
location | s

HTH,肖恩

答案 2 :(得分:1)

假设您想在提取数据后删除客户端列,您可以使用以下函数,该函数有3个参数 - x表,y json列和z要提取的列:

q)f:{((),y)_x,'((),z)#.j.k'[x y]}
q)f[c;`client;`firstName]
date       firstName
--------------------
2008.02.04 "John"
2015.01.02 "Scott"

这可以分解如下:.j.k'[x y]将使用.j.k提取解析和json数据到表中,((),z)#使用take operator #仅提取所需的列,然后使用x,'连接到原始表。最后一步是drop _带有((),y)_的json列。

需要使用(),进行接收和删除操作,因为它们希望传递一个列表,这确保了这种情况。

答案 3 :(得分:0)

虽然JSON解析已经集成在KDB'.j'命名空间(3.3及更高版本)中。 可以使用.j.k解析它。

select date, firstName:client@\:`firstName , lastName:client@\:`lastName from update .j.k each client from  c

您可以使用'.j.j'将kdb对象序列化为表示JSON的字符串。

答案 4 :(得分:0)

据我所知,您对保持客户端列不感兴趣。我就是这样做的:

((),`client) _ c,'{.j.k x}'[exec client from c]

你会得到一张像这样的表:

date       firstName lastName age
---------------------------------
2003.07.05 "John"    "Smith"  27
2005.02.25 "Scott"   "Tiger"  29