我如何找到相关的讲座

本文关键字:何找 | 更新日期: 2023-09-27 18:27:08

我有一个网站,可以显示可用讲座的信息。每个讲座都有一个标题,一个相关的演讲者,以及(潜在的)多个类别。数据库模式看起来像这样(警告:这是空中代码,因为我面前没有数据库)。。。

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#中使用实体框架模型来实现这一点,如果其中任何一个相关的话。

我如何找到相关的讲座

让我sktech给出一个基本想法:假设所有三个条件都可以在sql查询中表达,那么您应该得到加权的结果集,然后将它们放在一起union

第一个是简单的select ID, 10 as weight from lectures where ID <> ourLectureID and speakerID = ourSpeakerID

第二个将是具有较小权重的LecturesTopics之上的join,可能是4

让我们暂时忽略第三个查询的问题。

既然我们有了ID和权重的集合CCD_ 7;总和我的sql今天相当生疏,但我想到了这样的东西:select max(ID), sum(weight) as ranking from result1 group by ID order by ranking。。完成!

现在我已经有将近20年没有接触过SQL server了;-)但我认为它不太适合创建第三个查询。数据库设计器只会给你一个有趣的外观,并告诉你查询标题很糟糕;以及"为什么不添加keywords表…?"。。??

如果你不想这么做,我想你可以把所有的标题都拉到你的C#应用程序中,并使用它的字符串/集合/LINQ功能来过滤出有趣的单词,并创建具有第三排名的第三个查询;可能只有4个或更多字母的大写单词。。?

更新

以下是一个小例子,说明如何在一系列线条中找到最合适的线条:

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";
        }
    }
}

它使用了两个列表框和一个谚语文本文件。加载后,您可以单击第二个列表框,窗口标题将显示点击次数最多的行。

你会想做一些改变:

  • 从数据库中提取您的标题,包括它们的密钥
  • 使用非谓词创建更广泛、可扩展的文件
  • 对混合案件作出裁决
  • 不是创建一个结果,而是创建一组有序的行
  • 也许可以优化一些东西,这样你就不必多次拆分标题了