从KDB中包含JSON文本的列中提取多个列
我有一个表,其中包含一个包含JSON文本的列。我想解析该列并将不同的属性提取到多个列中从KDB中包含JSON文本的列中提取多个列,kdb,Kdb,我有一个表,其中包含一个包含JSON文本的列。我想解析该列并将不同的属性提取到多个列中 c:([] date:2?.z.d ; client:( "{ \"firstName\": \"John\", \"lastName\": \"Smith\", \"age\": 27 }" ; "{ \"firstName\": \"Scott\", \"lastName\": \"Tiger\", \"age\":29 }" ) ) 尽管JSON解析已经集成到KDB“.j”命名空间(3.
c:([] date:2?.z.d ; client:( "{ \"firstName\": \"John\", \"lastName\": \"Smith\", \"age\": 27 }" ; "{ \"firstName\": \"Scott\", \"lastName\": \"Tiger\", \"age\":29 }" ) )
尽管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的字符串。假设您希望在提取数据后删除客户端列,则可以使用以下函数,该函数有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'[xy]
将解析和json数据提取到一个表中,使用,((),z)
只提取所需的列,然后使用x'
将这些列连接到原始表中。最后一步是使用((),y)
访问json列
take和drop操作都需要使用
(),
,因为它们希望传递一个列表,这确保了这一点。据我所知,您对保持客户列的原样不感兴趣。我会这样做:
((),`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
如果您在表中的每个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
下面是从整个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
嗯,肖恩