2015-12-17 4 views
0

У меня есть веб-сайт, который показывает информацию о доступных лекциях. Каждая лекция имеет название, ассоциированный динамик и (потенциально) несколько категорий. Схема базы данных выглядит что-то вроде этого (предупреждение: это воздух-код, так как у меня нет базы данных перед мной) ...Как найти связанные лекции?

create table Lectures (
    ID int not null identity(1,1) primary key, 
    Title varchar(max) not null default '', 
    SpeakerID int not null foreign key references Speakers(ID) 
) 

create table Categories (
    ID int not null identity(1,1) primary key, 
    Name varchar(max) not null default '' 
) 

create table Lectures_Categories (
    ID int not null identity(1,1) primary key, 
    LectureID int not null foreign key references Lectures(ID), 
    CategoryID int not null foreign key references Categories(ID) 
) 

При просмотре сведений о лекции, я хотел бы быть в состоянии рекомендовать связанные лекции, но я не уверен, как это кодировать. Моя первая мысль о том, что следующие критерии будут использоваться для расчета релевантности (наиболее важной первой) ...

  • Общих категорий - то есть несколько категорий, разделяемых две лекции, тем более вероятно, что они должны быть связаны
  • Сходство по названию - т.е. чем больше слов разделяют две лекции, тем больше вероятность того, что они будут связаны.
  • же динамик

Если две лекций были одинаково ранжированы в соответствии с указанными выше критериями, я хотел бы ранжировать более новые выше старых.

Кто-нибудь знает, как я буду кодировать это? Я делаю это на C#, используя модель Entity Framework против базы данных SQL Server, если это имеет значение.

+1

Просто шпионить за пользователями, что они делают (как это делает Windows 10). Храните статистику и показывайте лекции, которые пользователи посещают вскоре после посещения конкретного (как это делает амазон). С некоторой фильтрацией они связаны *. – Sinatr

+1

@Sinatr Спасибо, но это, вероятно, не сработает, так как пользователи, вероятно, будут слушать лекцию, так будет на веб-странице в течение часа или около того. Они могут вернуться позже, но у них не будет большой истории непрерывного просмотра. Я ищу больше для того, чтобы найти связанные лекции, основываясь только на том, что находится в базе данных. –

+0

Я думаю, что одним из способов является то, что вы правильно классифицируете курсы в своей базе данных (неопределенные, например: биология, зоология, теоретическая физика, прикладная физика и т. Д. Каталоги), тогда, если курс под категорией находится в игре, вы можете вытащить другие курсы в этой категории. Также вы можете указать ссылку для динамика, если пользователь нажимает, а затем вытаскивает все лекции, предоставленные им. Разве это не начало ослаблять ваш мыслительный процесс? –

ответ

1

Позвольте мне Сколтех из основной идеи: Предположим, что все три критерия, могут быть выражены в SQL запросов вы должны получить весила наборы результатов, которые вы затем union вместе.

Первый будет просто select ID, 10 as weight from lectures where ID <> ourLectureID and speakerID = ourSpeakerID

Второй будет join над Lectures и Topics с меньшим весом, может быть 4.

Давайте проигнорируем проблемы с третьим запросом на данный момент.

Теперь, когда у нас есть набор result1 идентификаторов и весов, мы делаем группу & sum. Сегодня мой sql довольно ржавый, но я думаю о чем-то вроде этого: select max(ID), sum(weight) as ranking from result1 group by ID order by ranking .. Сделано!

Теперь я почти не касался SQL-сервера почти через 20 лет ;-), но я думаю, что он не подходит для создания третьего запроса. И дизайнер db только даст вам смешной взгляд и скажет вам, что запрос заголовка плохой плохой; и «почему вы не добавили таблицу keywords .. ??

Если вы не хотите, чтобы это было так, как я предполагаю, вы можете вытащить все Titles в ваше приложение C# и использовать его возможности string/collections/LINQ для фильтрации интересных слов и создания третьего запроса с третьим рангом; возможно, только заглавные слова с 4 буквами или больше ..?

Update

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

List<string> proverbs = new List<string>(); 
List<string> cleanverbs = new List<string>(); 
List<string> noverbs = new List<string>(); 

private void button1_Click(object sender, EventArgs e) 
{ 
    noverbs.AddRange(new[] { "A", "a", "by", "of", "all", "the", "The", 
     "it's", "it", "in", "on", "is", "not", "will", "has", "can", "under" }); 

    proverbs = File.ReadLines("D:\\proverbs\\proverbs.txt").ToList(); 
    cleanverbs = proverbs.Select(x => cleanedLine(x)).ToList(); 
    listBox1.Items.AddRange(proverbs.ToArray()); 
    listBox2.Items.AddRange(cleanverbs.ToArray()); 
} 

string cleanedLine(string line) 
{ 
    var words = line.Split(' '); 
    return String.Join(" ", words.ToList().Except(noverbs)); 
} 

int countHits(string line, List<string> keys) 
{ 
    var words = line.Split(' ').ToList(); 
    return keys.Count(x => words.Contains(x)); 
} 

private void listBox2_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    string line = listBox2.SelectedItem.ToString(); 
    int max = 0; 
    foreach (string proverb in cleanverbs) 
    { 
     var keys = proverb.Split(' ').ToList(); 
     int count = countHits(line, keys); 
     if (count > max && proverb != line) 
     { 
      max = count; 
      Text = proverb + " has " + max + " hits"; 
     } 
    } 
} 

Это делает использование двух ListBoxes и текстовый файл пословиц , При загрузке вы можете щелкнуть по второму списку, и заголовок окна отобразит строку с наибольшим количеством ударов.

Вы хотите, чтобы сделать несколько изменений:

  • тянуть свои названия из вашей базы, в том числе их ключей
  • создать более обширный и расширяемый файл с не-глаголами
  • решения о смешанно случай
  • создать не один результат, но упорядоченное множество линий
  • возможно оптимизировать несколько вещей, так что вам не нужно разделить тело названия более чем один раз
+0

Спасибо за ответ, но я думаю, что вы не правильно прочитали мой вопрос. Мое правило №1 для сопоставления - это общие категории, и я ищу способ разработки их ранжирования. Я знаю, что мне нужно какое-то соединение над лекциями и категориями, но как мне это сделать? Пожалуйста, прочитайте первый вопрос в моем вопросе, что я хочу делать. –

+0

Что касается третьего запроса, у нас нет таблицы ключевых слов, потому что это новое требование. Добавление одного не поможет, если мы не сможем автоматически заполнить его из заголовков (в этом случае мы могли бы просто извлечь ключевые слова из названий при выполнении запроса), потому что администраторы сайта никогда не потрудились добавлять ключевые слова в несколько тысяч лекции уже там, и, вероятно, забудут сделать это и для новых. Если это сработает, мне нужно будет вытащить ключевые слова из заголовков при поиске. Вот почему я спрашивал, знал ли кто-нибудь об этом. Thx –

+0

Я добавил пример, который показывает основную идею обработки третьего запроса. Заметьте, что это очень просто, но вы можете начать ... – TaW