Dictionary 如何在嵌套字典中更新表中的条目?

Dictionary 如何在嵌套字典中更新表中的条目?,dictionary,nested,kdb,q-lang,Dictionary,Nested,Kdb,Q Lang,我正在尝试创建一个订单簿数据结构,其中一个顶级字典包含3种基本订单类型,每种类型都有一个买卖双方,每一方都有一个表列表,每个表对应一个报价器。例如,如果我想检索googlestock的所有类型1的ask订单,我会调用book[`orderType1][`ask][`GOOG]。我使用以下方法实现了这一点: bookTemplate: ([]orderID:`int$();date:"d"$();time:`time$();sym:`$();side:`$(); orderType:`$();pr

我正在尝试创建一个订单簿数据结构,其中一个顶级字典包含3种基本订单类型,每种类型都有一个买卖双方,每一方都有一个表列表,每个表对应一个报价器。例如,如果我想检索googlestock的所有类型1的ask订单,我会调用book[`orderType1][`ask][`GOOG]。我使用以下方法实现了这一点:

bookTemplate: ([]orderID:`int$();date:"d"$();time:`time$();sym:`$();side:`$();
orderType:`$();price:`float$();quantity:`int$());
bookDict:(1#`)!enlist`orderID xkey bookTemplate;
book: `orderType1`orderType2`orderType3 ! (3# enlist(`ask`bid!(2# enlist bookDict)));
使用book[`orderType1][`ask][`ticker]进行数据检索似乎效果良好。当我尝试将新订单添加到特定订单簿时出现问题,例如:

testorder:`orderID`date`time`sym`side`orderType`price`quantity!(111111111;.z.D;.z.T;
`GOOG;`ask;`orderType1;100.0f;123);
book[`orderType1][`ask][`GOOG],:testorder;

执行最后一个查询会出现“分配错误”。原因是什么?如何解决这个问题?

这里有几个问题。第一个是,虽然您可以使用一系列在线重复键查找字典,例如

q)book[`orderType1][`ask][`GOOG]
orderID| date time sym side orderType price quantity
-------| -------------------------------------------
您不能像这样分配值(只能分配一个级别)。更好的方法是使用点索引(和点修改以重新指定值)。但是,问题是,由于字典列表是统一的,所以图书字典的值正在被压平到一个表中。所以这是失败的:

q)book . `orderType1`ask`GOOG
'rank
你可以通过检查终端看到它是如何变平的

q)book
          | ask
----------| -----------------------------------------------------------------
orderType1| (,`)!,(+(,`orderID)!,`int$())!+`date`time`sym`side`orderType`pric
orderType2| (,`)!,(+(,`orderID)!,`int$())!+`date`time`sym`side`orderType`pric
orderType3| (,`)!,(+(,`orderID)!,`int$())!+`date`time`sym`side`orderType`pric
为了防止这种扁平化,您可以通过添加一个泛型null来强制该值为混合列表

q)book: ``orderType1`orderType2`orderType3 !(::),(3# enlist(`ask`bid!(2# enlist bookDict)));
然后看起来是这样的:

q)book
          | ::
orderType1| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord
orderType2| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord
orderType3| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord
点索引现在可以工作了:

q)book . `orderType1`ask`GOOG
orderID| date time sym side orderType price quantity
-------| -------------------------------------------
这意味着修正点现在也会起作用

q).[`book;`orderType1`ask`GOOG;,;testorder]
`book
q)book
          | ::
orderType1| `ask`bid!+``GOOG!(((+(,`orderID)!,`int$())!+`date`time`sym`side`o
orderType2| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord
orderType3| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord

最后,我建议阅读关于如何最好地存储图书数据的FD白皮书:

这里有几个问题。第一个是,虽然您可以使用一系列在线重复键查找字典,例如

q)book[`orderType1][`ask][`GOOG]
orderID| date time sym side orderType price quantity
-------| -------------------------------------------
您不能像这样分配值(只能分配一个级别)。更好的方法是使用点索引(和点修改以重新指定值)。但是,问题是,由于字典列表是统一的,所以图书字典的值正在被压平到一个表中。所以这是失败的:

q)book . `orderType1`ask`GOOG
'rank
你可以通过检查终端看到它是如何变平的

q)book
          | ask
----------| -----------------------------------------------------------------
orderType1| (,`)!,(+(,`orderID)!,`int$())!+`date`time`sym`side`orderType`pric
orderType2| (,`)!,(+(,`orderID)!,`int$())!+`date`time`sym`side`orderType`pric
orderType3| (,`)!,(+(,`orderID)!,`int$())!+`date`time`sym`side`orderType`pric
为了防止这种扁平化,您可以通过添加一个泛型null来强制该值为混合列表

q)book: ``orderType1`orderType2`orderType3 !(::),(3# enlist(`ask`bid!(2# enlist bookDict)));
然后看起来是这样的:

q)book
          | ::
orderType1| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord
orderType2| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord
orderType3| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord
点索引现在可以工作了:

q)book . `orderType1`ask`GOOG
orderID| date time sym side orderType price quantity
-------| -------------------------------------------
这意味着修正点现在也会起作用

q).[`book;`orderType1`ask`GOOG;,;testorder]
`book
q)book
          | ::
orderType1| `ask`bid!+``GOOG!(((+(,`orderID)!,`int$())!+`date`time`sym`side`o
orderType2| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord
orderType3| `ask`bid!+(,`)!,((+(,`orderID)!,`int$())!+`date`time`sym`side`ord

最后,我建议您阅读关于如何最好地存储图书数据的FD白皮书:

非常感谢。您能解释一下为什么不应该在键控表上使用append(逗号)吗?似乎。[`book;`orderType1`ask`GOOG;,;testorder]工作正常(即,如果订单ID不在表中,则追加新条目,否则更新现有条目)。它的速度也快得多(~36秒用于追加100000份订单,~7秒用于追加100000份订单)。他们在你链接的FD论文中也这样做了(例如,updBySymSide2,其中基础表以价格为键)。你说得对,我的错。我以为我的测试失败了。我会编辑我的答案谢谢,谢谢。您能解释一下为什么不应该在键控表上使用append(逗号)吗?似乎。[`book;`orderType1`ask`GOOG;,;testorder]工作正常(即,如果订单ID不在表中,则追加新条目,否则更新现有条目)。它的速度也快得多(~36秒用于追加100000份订单,~7秒用于追加100000份订单)。他们在你链接的FD论文中也这样做了(例如,updBySymSide2,其中基础表以价格为键)。你说得对,我的错。我以为我的测试失败了。我会修改我的答案谢谢