我有一个包含JSON文本列的表。我想解析该列并将不同的属性提取到多个列。
c:([] date:2?.z.d ; client:( "{ \"firstName\": \"John\", \"lastName\": \"Smith\", \"age\": 27 }" ; "{ \"firstName\": \"Scott\", \"lastName\": \"Tiger\", \"age\":29 }" ) )
答案 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