有效地计算SQL中的重要术语

Ali*_*xel 13 sql query-optimization aggregation elasticsearch significant-terms

我刚刚向ElasticSearch介绍了重要的术语聚合,并且对这个度量标准的优秀和相关程度感到非常惊讶.对于那些不熟悉它的人来说,这是一个非常简单的概念 - 对于给定的查询(前景集),给定的属性根据背景集的统计显着性进行评分.

例如,如果我们要查询英国交通警察中最重要的犯罪类型:

C = 5,064,554 -- total number of crimes
T =    66,799 -- total number of bicycle thefts
S =    47,347 -- total number of crimes in British Transport Police
I =     3,640 -- total number of bicycle thefts in British Transport Police
Run Code Online (Sandbox Code Playgroud)

通常,自行车盗窃仅占犯罪的1%(66,799/5,064,554),但对于处理铁路和车站犯罪的英国交通警察来说,7%的犯罪(3,640/47,347)是自行车盗窃.频率增加了7倍.

"自行车盗窃"的意义在于 [(I/S) - (T/C)] * [(I/S) / (T/C)] = 0.371...

哪里:

  • C是集合中所有文档的编号
  • S是与查询匹配的文档数
  • T是具有特定术语的文档数
  • 是与ST相交的文档数

由于实际原因(我拥有大量的数据和巨大的ElasticSearch内存要求),我希望在SQL中或直接在代码中实现重要的术语聚合.

我一直在寻找一些方法来潜在地优化这种查询,特别是降低内存需求和提高查询速度,但代价是一些错误余量 - 但到目前为止我还没有破解它.在我看来,这:

  • 变量CS很容易缓存或查询.
  • 变量T可以从Count-Min Sketch派生而不是查询数据库.
  • 然而,变量I似乎无法用T的Count-Min Sketch得出.

我也在看MinHash,但从描述中看来它似乎无法在这里应用.

有谁知道一些有助于解决这个问题的聪明的算法或数据结构?

Mar*_*rkH 10

我怀疑SQL impl会更快.Lucene提前保持C和T的值.S是从查询结果派生的简单计数,我使用O(1)数据结构查找.主要成本是在所选字段中观察到的每个术语的许多T查找.使用min_doc_count通常有助于大幅减少这些查找的次数.

出于实际原因(我拥有大量的数据和巨大的ElasticSearch内存要求

您是否考虑过使用doc值来更好地管理elasticsearch内存?请参阅https://www.elastic.co/blog/support-in-the-wild-my-biggest-elasticsearch-problem-at-scale