Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建更精确的搜索?_C#_Linq - Fatal编程技术网

C# 如何创建更精确的搜索?

C# 如何创建更精确的搜索?,c#,linq,C#,Linq,我需要一个精确的搜索函数,无论是在jquery还是c中。如果可能,我希望搜索像谷歌一样精彩:- 下面是c代码: 简要说明: 这将搜索数据库中具有完整信息的所有用户。它搜索除当前登录用户之外的所有用户 string[] ck = keyword.Split(new string[] { " ", ",", "." }, StringSplitOptions.RemoveEmptyEntries); using (dbasecore db =

我需要一个精确的搜索函数,无论是在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();
}  
结果是:

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

嗯。。。您确实在select中指定了特定的顺序。我猜这就是你得到的订单,对吧


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

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

1编写自己的排名算法。这意味着,您可以使用Linq获得结果,然后使用自己的排名函数对结果进行排序-这可能是一些简单的事情,比如将请求拆分为单词并计算每个结果中出现的单词数,或者是一些复杂的事情,比如使用词干分析来查找不同形式的请求词,测量词之间的距离,增加一些词的数量,我不建议这样做,因为Like查询在SQL上速度很慢,您需要编写一些已经编写好的东西

2使用Sql Server全文搜索:。虽然我不喜欢使用SQLServer全文搜索,但它是一个好的可行的解决方案


3使用第三方全文搜索,有一些替代方案,Lucene可能是.net中使用最多的。这给了您速度和灵活性,您可以以各种方式为数据编制索引,但您的响应速度肯定足够快。Lucene上还有一个API,比如我最喜欢的Solr,虽然对你来说可能太多了。

像谷歌那样出色的API可能是远远不够的,但你可以用一种非常简单的技术实现一些可以接受的东西。我的想法是:

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

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

不确定LINQ是否支持三元运算符,但如果不支持,您也可以使用循环和手动方法实现同样的功能。所有条件的总和将给予更接近的候选人更高的分数。然后,您可以按此列进行排序。

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

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;

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

在全文中有排名,使用这是您的列全文我接受这个答案,因为它简单且工作良好。谢谢你的例子。