对聚合结果进行交叉过滤

Crossfilter on aggregated results

我正在使用 Crossfilter(DC.JS,因此使用 D3)来可视化大量数据。我喜欢图书馆的互动特性,但我的数据很快就变得太大了。我认为适合处理此问题的最佳方法是在数据太大时预先聚合我的数据。我很难找出 Crossfilter 如何(以及是否)可以处理此类数据。

为了说明,我拥有的数据的形式是

[
    {"date":"01-01-2016","food": "apple", "gender": "M", "country": "DE"},
    {"date":"01-01-2016","food": "pear", "gender": "M", "country": "DE"},
    {"date":"01-01-2016","food": "apple", "gender": "F", "country": "DE"},
    {"date":"01-01-2016","food": "apple", "gender": "F", "country": "UK"},
    {"date":"01-02-2016","food": "pear", "gender": "M", "country": "UK"},
    {"date":"01-02-2016","food": "pear", "gender": "M", "country": "UK"},
    {"date":"01-02-2016","food": "apple", "gender": "M", "country": "US"},
    ...
]

我将如何通过可视化围绕日期字段进行旋转?所以知道在 01-01,我有 3 个人买苹果,例如 2 个来自德国(1 男,1 女)和 1 个来自英国?

我想我可以通过为每个组合计算一种数据立方体然后计算它来做到这一点,就像这样:

[
    {"date":"01-01-2016","food": "apple", "gender": "M", "country": "DE", "count": 100000},
    {"date":"01-01-2016","food": "pear", "gender": "M", "country": "DE", "count": 72651},
    {"date":"01-01-2016","food": "apple", "gender": "F", "country": "DE", "count": 12345},
    {"date":"01-01-2016","food": "apple", "gender": "F", "country": "UK", "count": 9287164},
    {"date":"01-02-2016","food": "pear", "gender": "M", "country": "UK", "count": 291732743},
    {"date":"01-02-2016","food": "apple", "gender": "M", "country": "US", "count": 128176376}
    ...
]

但是通过这种设置,我在数据量上并没有赢得多少,我也不确定how/if Crossfilter 是否可以处理以这种方式表示的数据。

这个问题很宽泛*,但这里是。

在 Crossfilter 中有几种方法可以处理这个问题。我将按复杂程度或多或少地列出它们:

  1. 通过使用标记作为键和值来缩小您的记录。例如,{"date":"01-01-2016","food": "apple", "gender": "M", "country": "DE"} 可能会变成 {"d":"01-01-2016","f": "a", "g": "M", "c": "DE"},这将为每条记录节省几个字节。
  2. 按照您的描述预先汇总您的记录。对于计数,这很容易。您按照预聚合记录数量的描述进行预聚合,然后使用 crossfilter.group.reduceSum(function(d) { return d.count; }) 或类似的方法来聚合计数总和。对于其他类型的聚合,它变得更加复杂并且可能需要自定义 reducer,但通常有些事情是可能的。如果您遇到特定聚合问题的问题,请创建一个关于该问题的新问题并准确地列出问题。
  3. 只需从服务器端驱动一个基于 Crossfilter 的 API。您将失去一些交互性,但这是一种可靠的方法。此处记录了几种解决方案:https://github.com/dc-js/dc.js/wiki/FAQ#how-do-i-replace-crossfilter-with-a-server-side-solution
  4. 使用组合方法,在服务器端进行一些预聚合,但仍然在客户端处理过滤和最终聚合。我所知道的使用 Crossfilter 执行此操作的唯一示例是:http://lcadata.info (source-code here: https://github.com/esjewett/lcadata)。这是一个真正依赖数据的解决方案,这里没有通用库。

与所有这些正交的是将 Crossfilter 转移到网络工作者,这有助于交互性,但并不能真正帮助解决数据量问题。

我的建议:执行上面的#1 并确定在您需要的交互级别下您可以支持多少条记录。然后,如有必要,实施#2。如果这还不够,请确定#3 是否是一个选项,如果是,则执行此选项。否则请考虑#4,但请理解您正在执行一项相当高级的任务,并且将在很大程度上开辟自己的道路。

*为了回答您的任何具体问题,我们需要更多信息,例如您尝试加载显示的类型的确切记录数、您实际需要的维度、您将要加载的组类型需要创建等