3

当前状态

  • .NET 4.0 应用程序 (WPF)
  • 数据库:SQLCE
  • 表(简化):文档、标签、DocumentsTags [n:n]
  • 大约 2000 个文档和 600 个标签(标签可以分配给多个文档)
  • 标签 = 关键字 = 标签

案子

用户有一个大的文档数据库,他可以使用标签云对其进行过滤。标签显示一个名称(标签名称本身)和一个数字,该数字是具有相应标签的文档的总数。如果用户选择标签,则仅显示带有所选标签的文档。动态标签云现在应该只显示过滤文档上的可用标签,并更新计数。

问题

它很慢。在每个选定的标签之后,我们需要再次评估所有文档以计算标签。我们目前以递归方式执行此操作,因此我们检查每个文档都有哪些标签。我们正在寻找另一种解决方案(缓存、更好的算法,您的想法?)。

相似之处

stackoverflow、del.icio.us 也有标签云。自己检查一下。他们是如何做到的呢?我知道存储过程将是一种解决方案,但根据我们的数据库开发人员,这在 SQLCE 上不可用。

4

2 回答 2

1

您可以使用两个倒排索引,其中每个标签都是两者的键。

一个倒排索引实际上是map:Tags->list of Tags[所有与键共同出现的标签]
第二个将是map:Tags->list of Docs[所有与每个标签共同出现的文档]。

在选择了一些标签后计算相关的文档集只是倒排索引的一个交集,可以有效地完成。
此外,查找修改后的标签云也是倒排索引的一个交集。

请注意,倒排索引可以离线创建,创建它是map-reduce使用的经典示例。

该线程讨论如何有效地找到倒排索引中的交集

于 2012-02-15T11:52:36.147 回答
0

您应该在单个查询中进行第二阶段搜索,例如

SELECT
  tags.id AS tagid,
  tags.name AS tagname,
  count(*) AS tagcount
FROM
  tags
  INNER JOIN DocumentsTags AS tda on tda.tagid=tags.id
  INNER JOIN DocumentsTags AS tdb on tda.documentid=tdb.documentid
WHERE
  tdb.tagid=<selected tag id>
GROUP BY
  tags.id

编辑

在您发表评论后,这就是您应该用于第一阶段查询的内容(即:尚未选择标签,列表中的所有文档)

SELECT
  tags.id AS tagid,
  tags.name AS tagname,
  count(*) AS tagcount
FROM
  tags
  INNER JOIN DocumentsTags AS tda on tda.tagid=tags.id
GROUP BY
  tags.id
于 2012-02-15T11:52:47.337 回答