使用linq实时搜索多个数据库字段

时间:2014-07-27 14:56:03

标签: c# database linq livesearch

我基本上都在寻找谷歌类型'搜索我的数据库。

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

当然,简单地拆分游戏,书籍和电影搜索都没有问题,但如果我有一个搜索字段,我会真的觉得很棒,主要是因为我有时会把书与电影混淆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 search fields method但它在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"进一步,但是查询我从上一个查询得到的结果列表或重新查询整个数据库会更好吗?

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

那么这样做的最佳做法是什么?我发现了一些像提到的那样的例子,但我正在寻找最快的用户证明&#34; (意思是无论搜索多么奇怪,它仍然需要提出正确的结果)

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

The model of my database

P.S。我不是最好的数据库设计师,所以如果你找到了不同的东西让我知道(还有很多需要学习的东西)

1 个答案:

答案 0 :(得分:1)

你问的是一个非常深刻的问题,我不认为有一个&#34;权利&#34;回答,但我确实认为有好的&#34;并且&#34;坏&#34;根据您的要求和假设进行处理。

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

  1. 在给定特定查询字符串的情况下,您需要确定数据行R
  2. 的排序
  3. 此排序应该是确定性的
  4. 此顺序应易于计算
  5. 此排序应反映您的搜索字符串与R
  6. 成员之间的相似性或相关性

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

    1. 搜索字符串包含在R
    2. 的成员中
    3. R的更多成员使用搜索字符串表示更相关的结果
    4. R的某些成员比其他成员更重要
    5. 我们应该允许拼写错误 - 即部分匹配是值得的
    6. 然后我们可以确定一个&#34;得分&#34; R行的行如下:

      1. R的每个成员获得一个&#34;体重&#34;最小值为1且无最大值
      2. R的分数等于每个成员的权重除以&#34;距离&#34;在成员和查询字符串之间
      3. 距离是根据众所周知的字符串距离指标定义的,例如Levenshetin或SoundEx
      4. 例如,如果您的R有成员NameDescriptionURL,那么您可以对这些10010进行加权,和1分别应用Levenshtein指标。

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

        但是得分是将问题简化为更容易解决的问题的有效方法。