Поиск более быстрого алгоритма для подсчета тегов / ключевых слов / меток в базе данных документов для динамического облака тегов - PullRequest
3 голосов
/ 15 февраля 2012

Текущее состояние

  • .NET 4.0 Application (WPF)
  • База данных: SQLCE
  • Таблицы (упрощенно): документы, теги, теги документов [n: n]
  • примерно 2000 документов и 600 тегов (теги могут быть назначены нескольким документам)
  • теги = ключевые слова = этикетки

Case

У пользователя есть большая база данных документов, которую он может фильтровать с помощью облака тегов. Теги отображают имя (само имя тега) и число, которое является общим количеством документов с соответствующим тегом. Если пользователь выбирает тег, отображаются только документы с выбранным тегом. Облако динамических тегов теперь должно отображать только доступные теги в отфильтрованных документах с обновленным номером счета.

Задача

Это медленно. После каждого выбранного тега нам нужно снова оценить все документы для подсчета тегов. В настоящее время мы делаем это рекурсивно, поэтому проверяем каждый документ на наличие тегов. Мы ищем другое решение (кеширование, лучший алгоритм, ваша идея?).

Сходства

stackoverflow, del.icio.us также имеет облака тегов. Проверьте себя. Как они это делают? Я знаю, что хранимые процедуры были бы решением, но, по словам нашего разработчика базы данных, это не доступно в SQLCE.

Ответы [ 2 ]

1 голос
/ 15 февраля 2012

Вы можете использовать два инвертированных индекса , где каждый тег будет ключевым в обоих.

Один инвертированный индекс на самом деле будет map:Tags->list of Tags [все теги, которые совпадают с ключом]
Второй будет map:Tags->list of Docs [все документы, которые встречаются с каждым тегом].

Вычисление соответствующего набора документов после выбора некоторых тегов - это просто пересечение по инвертированному индексу, которое можно сделать эффективно.
Кроме того, обнаружение модифицированного облака тегов снова является пересечением по инвертированному индексу.

Обратите внимание, что инвертированный индекс можно создавать в автономном режиме, и его создание является классическим примером использования map-Reduce .

В этой теме обсуждается, как эффективно найти пересечение в инвертированном индексе

0 голосов
/ 15 февраля 2012

Вы должны выполнить второй этап поиска в одном запросе, что-то вроде

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
...