4

首先,让我解释一下我正在构建的内容:

  • 我有一个 D3.js 强制布局图,它植根于中心,周围散布着一堆节点。中心节点是某种实体,它周围的节点是与根有某种关联的其他实体。边缘是实际的关系(即两者是如何相关的)。

  • 可以单击外部节点以使目标实体居中并加载其关系

  • 该图是“以自我为中心”的,因为每次单击节点时,它都会成为中心,并且只显示与自身直接相关的关系。

我的设置,以防万一:

  • 我通过 Node.js 提供 API,它将请求转换为对具有大量数据集的 CouchDB 服务器的查询。

  • D3.js 用于布局,除了 jQuery 和 Bootstrap,我没有使用任何其他客户端库。如果有任何对这个缓存任务有帮助的,我愿意接受建议:)

我的想法:

  • 我每次都可以轻松地抓取图表的几个级别(通过多次列出和扩展子项的过程递归),但是由于单击任何给定节点会加载完全不相关的数据,因此不能保证产生高比例的类似数据为根加载的数据。这似乎完全是浪费,实际上是朝相反方向迈出的一步——我最终会以这种方式进行更多处理!

  • 我可以轻松地维护已检索到的实体的哈希表,并在从服务器请求该实体的数据之前检查该列表。无论我实施何种缓存策略,我都可能最终会这样做,因为它是一种非常简单的减少查询的方法。

现在,你建议我如何缓存这些数据?

有没有什么超级有效的策略来做这种缓存?非常欢迎服务器和客户端选项。这个过程涉及大量数据,任何查询/处理的减少都让我领先于游戏。

谢谢!

4

2 回答 2

2

在客户端,我将拥有节点,并且让它们的子节点要么是一组子节点,要么是作为这些子节点承诺的函数。当您单击给定节点时,如果您有数据,请立即显示它。否则发送将填充它的 AJAX 请求。

每当您显示一个节点(未居中)时,为显示的节点的子节点创建 AJAX 请求的异步列表并开始请求它们。这样当用户点击时,你就有可能已经缓存了它。如果没有,那么,您尝试过并且没有花费任何费用。

一旦你让它工作,决定多少层深度是有意义的。我的猜测是幻数很可能是 1。除此之外,响应速度的回报迅速下降,而服务器负载迅速上升。但是让点击尽快返回是一个相当大的 UI 胜利。

于 2012-06-26T22:14:00.653 回答
1

我认为你需要做两件事:

  1. 减少您提出的请求数量
  2. 降低请求成本

正如 btilly 指出的那样,您可能最好为每个可见节点请求相关节点,以便如果单击它们,则可视化会立即响应——您不希望查询加上传输时间作为响应滞后。

但是,如果您非常需要减少请求数量,则表明您的请求本身成本太高,因为总负载为requestCost * numRequests. 考虑寻找方法来预先计算与每个节点相关的节点集,以便请求是读取请求而不是完整的 DB 查询。如果您觉得这听起来很难,那么这正是您每次搜索新事物时 Google 所做的;他们无法在您每次开始输入时搜索互联网,因此他们会提前进行搜索并缓存。

这可能意味着一定程度的非规范化;如果您有缓存查询,则不能保证它们是同步的,但问题是您的数据集是否更改;是一次写入,多次读取吗?

为了最小化所有这些节点及其关系所需的空间,更多地将其视为粒子相互作用问题;通过对空间进行分区,您可以对节点进行分组,以便您只需要查询一组节点的聚合邻居,并将其存储。这样,您可以对每个请求进行更小的过滤,而不是完整的数据库查询。如果它是 O(n log n) 并且你将 na 缩小一百倍,那么它的速度会快 100 倍以上。

于 2012-11-06T15:53:19.123 回答