5

无论是在 jquery 还是 c# 中,我都需要一个准确的搜索功能。如果可能的话,我希望搜索像谷歌一样出色:-)

所以这里是c#代码:

简要说明:
这将搜索数据库中具有完整信息的所有用户。它搜索除当前登录用户之外的所有用户。

string[] ck = keyword.Split(new string[] { " ", ",", "." },
                            StringSplitOptions.RemoveEmptyEntries);

using (dbasecore db = ConfigAndResourceComponent.BaseCampContext())
{
    var results = (from u in db.users
                   join uinfo in db.userinfoes 
                        on u.UserID equals uinfo.UserID
                   where u.UserID != userid && 
                        (ck.Contains(u.LastName) || ck.Contains(u.FirstName) ||
                         ck.Contains(u.MiddleName) || ck.Contains(u.LoginID))
                   orderby u.LastName, u.FirstName, u.MiddleName ascending
                   select uinfo).Skip(skip).Take(take).ToList();

    return (from i in results select new UserInfo(i)).ToList();
}  

结果:

在此处输入图像描述

包围的名称必须位于搜索项的顶部,因为它与更多关键字匹配。
任何的想法?

4

4 回答 4

5

有几种方法可以实现您想要的:

1)编写自己的排名算法。这意味着,您使用 Linq 获得结果,然后使用自己的排名函数对它们进行排序 - 这可能很简单,例如将请求拆分为单词并计算每个结果中出现的单词或复杂的东西,例如使用词干查找不同形式的请求术语,测量术语之间的距离,提升一些术语等。我不建议这样做 - 因为LikeSQL 上的查询很慢,你需要写一些已经写好的东西。

2)使用Sql Server全文搜索: http: //msdn.microsoft.com/en-us/library/ms142524 (v=sql.105).aspx 。虽然我不喜欢使用 SQL Server 全文搜索,但它是一个很好且可行的解决方案。

3)使用第三方全文搜索,有一些替代方案,Lucene(http://www.codeproject.com/Articles/29755/Introducing-Lucene-Net)可能是.net中使用最多的。这为您提供了速度和灵活性,您可以以各种方式索引您的数据,但您肯定足够响应索引它。在 Lucene 之上还有 API,比如我最喜欢的 Solr——尽管在你的情况下它可能太多了。

于 2013-05-29T12:06:30.787 回答
1

与 Google 一样出色可能相去甚远,但您可以使用非常简单的技术实现可接受的目标。这是想法:

在您的 WHERE 子句中ck.Contains(u.LastName) || ck.Contains(u.FirstName),您可以添加一个表达式,为每个成功的标准(根据其相对权重)分配一个值,而不是执行 WHERE ,并将它们相加以获得最终分数。例如:

WHERE (ck.Contains(u.LastName)? 1 : 0) + (ck.Contains(u.FirstName)? 2 : 0) + ...

不确定 LINQ 是否支持三元运算符,但如果不支持,您也可以使用循环和手动方法实现相同的目的。所有术语的总和将为更接近匹配的候选人提供更高的分数。然后,您可以按此列排序。

于 2013-05-29T12:16:58.247 回答
1

为简单起见,我将使用一个带有用户实体的表,如下所示:

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleName { get; set; }
}

这是查询(在 EF 中工作),它计算每个用户的匹配值,然后只选择匹配某些关键字的那些,按匹配值排序结果:

var keywords = new [] {"Sergey", "Berezovskiy"};

var users = from u in context.Users
            let match = (keywords.Contains(u.FirstName) ? 1 : 0) +
                        (keywords.Contains(u.LastName) ? 1 : 0) +
                        (keywords.Contains(u.MiddleName) ? 1 : 0)
            where match > 0
            orderby match descending, 
                    u.LastName, u.FirstName
            select u;

范围变量match将具有从0(如果没有字段匹配关键字)到3(如果所有字段匹配)的值。

于 2013-05-29T12:33:04.810 回答
0

嗯......你确实在你的select. 我想这就是你得到的命令,对吧?

编写一个排名函数,通过计算结果中存在多少搜索词来对结果进行排名...

于 2013-05-29T12:04:40.553 回答