0

我基本上是在寻找我的数据库的“谷歌类型”搜索。

我目前正在创建一个存储书籍(和作者)、游戏电影(以及未来更多)的应用程序。显然,应用程序还需要能够快速搜索数据库中的任何这些项目。

当然,简单地将游戏、书籍和电影搜索分开是没有问题的,但如果我有一个搜索字段来搜索所有内容,我真的会觉得很棒,主要是因为我有时会将书籍与电影混淆 xD

现在起初我认为这是一个很好的方法(只是搜索书籍):

List<Book> books = (from b in le.Book
                    where (b.Title + " " + b.Author.FirstName + " " +
                    b.Author.Surname).Contains(search)
                    select b).OrderBy(b => b.Title).ToList();

这很容易,并且可以在小型数据库中正常工作,并且当您以正确的顺序键入搜索时。所以使用这个搜索看起来像:

The fault in our stars John Green

但如果有人要输入:

John Green The fault in our stars
The fault in our stars - John Green

或者你能想出什么变化,它都会失败。

我确实在这里找到了一个很好的 SQL 查询示例:MYSQL 搜索字段方法,但它在 SQL 中,我不知道如何将其重写为 linq。因为数据库(将要)包含数千条记录,所以我不能只做:

var total = (from b in le.Book
             select new { b.ID, FullDescription = (b.Title + " " +
             b.Author.FirstName + " " + b.Author.Surname) });
string[] searchArr = search.split(' ');
List<int> ids = new List<int>();
foreach(string s in searchArr)
{
    ids.addRange((from t in total
                  where t.FullDescription.Contains(s).ToList());
}

foreach 循环会减慢它的速度(我知道必须有更好的方法来创建可变数量的 where 语句,但我也不知道该怎么做)。

但是,是的,它var total会变得巨大。

当然,还有一部分是让它成为实时搜索,所以每次输入一个字符时它都会更新列表视图,所以如果我输入:"jo"我会得到一个带有结果的列表,然后我可以通过输入进一步定义它,"joh"但它会是更好地查询我从上次查询中获得的结果列表或重新查询整个数据库?

另外我需要考虑退格,所以如果有人输入"jo"但想要"ja"我需要重新查询整个数据库,对吗?

那么这样做的最佳实践是什么?我找到了很多像上面提到的例子,但我正在寻找最快的“用户证明”(这意味着无论搜索多么奇怪,它仍然需要得出正确的结果)

我的数据库模型(仅包含书籍、作者)

我的数据库模型

PS 我不是最好的数据库设计师,所以如果你发现你会做不同的事情,请告诉我(还有很多东西要学)

4

1 回答 1

1

您提出了一个非常深刻的问题,我认为没有“正确”的答案,但我确实认为考虑到您的要求和假设,有“好”和“坏”的方法。

从根本上说,您正在尝试完成以下任务:

  1. 给定一个特定的查询字符串,您想确定数据行的排序R
  2. 这种排序应该是确定性的
  3. 这个排序应该很容易计算
  4. 此排序应反映您的搜索字符串与R

你必须首先接受,除非我们更好地定义问题,否则这更像是一门艺术而不是一门科学。这里的“相关性”没有明确定义。但是,我们可以对可能相关的内容做出一些常识性假设。例如,我们可以说相关结果具有以下品质:

  1. 搜索字符串包含在R
  2. 搜索字符串中的更多成员R表示更相关的结果
  3. 某些成员R比其他成员更重要
  4. 我们应该允许错别字/错误 - 即,部分匹配是值得的

然后我们可以确定R行的“分数”,如下所示:

  1. 每个成员R都有一个“权重”,最小值为1,没有最大值
  2. 分数R等于每个成员的权重之和除以成员与查询字符串之间的“距离”
  3. 距离是根据著名的字符串距离度量来定义的,例如 Levenshetin 或 SoundEx

例如,如果您R有成员NameDescriptionURL,您可以分别对这些10010和 进行加权1,并应用 Levenshtein 度量。

这甚至还没有接近冰山一角,因为这将是一个糟糕的算法,以至于它毫无用处。更好的方法包括交叉引用数据行的成员、对照已知字典查找成员以及开发基于证据的模型来对结果进行评分。

但是评分是将问题简化为更容易陈述的有效方法。

于 2014-07-28T09:50:00.273 回答