【问题标题】:Search Database - ASP.NET MVC C#搜索数据库 - ASP.NET MVC C#
【发布时间】:2009-10-03 06:34:37
【问题描述】:

我正在尝试在我的 ASP.NET MVC(C#、Linq-to-Sql)网站中实现完整的搜索功能。

该站点由大约 3-4 个表组成,其中包含大约 1-2 列我要搜索。

这是我目前所拥有的:

    public List<SearchResult> Search(string Keywords)
    {
        string[] split = Keywords.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        List<SearchResult> ret = new List<SearchResult>();
        foreach (string s in split)
        {
            IEnumerable<BlogPost> results = db.BlogPosts.Where(x => x.Text.Contains(s) || x.Title.Contains(s));

            foreach (BlogPost p in results)
            {
                if (ret.Exists(x => x.PostID == p.PostID))
                    continue;

                ret.Add(new SearchResult
                {
                    PostTitle= p.Title,
                    BlogPostID = p.BlogPostID,
                    Text=p.Text
                });

            }
        }
        return ret;
    }

如您所见,我有一个用于关键字的 foreach 和一个在表格上运行的内部 foreach(我会为每个表格重复它)。

这似乎效率低下,我想知道是否有更好的方法来为数据库创建搜索方法。

另外,我可以对数据库中的列做些什么,以便更快地搜索它们?我读过一些关于索引它们的东西,这只是我在 SQL Management Studio 中看到的“全文索引”True/False 字段吗?

【问题讨论】:

    标签: asp.net-mvc database search


    【解决方案1】:

    另外,我可以对 数据库,以便他们可以 搜索更快?我读了一些东西 关于索引它们,仅仅是 “全文索引”真/假字段 我在 SQL Management Studio 中看到了吗?

    是的,启用全文索引通常会大大提高这种情况下的性能。但不幸的是,它不能自动与 LIKE 运算符一起使用(这就是您的 LINQ 查询正在生成的内容)。因此,您必须使用内置全文搜索功能之一,例如 FREETEXT、FREETEXTTABLE、CONTAINS 或 CONTAINSTABLE。

    只是为了解释一下,您的原始代码将比全文搜索慢得多,因为它通常会导致表扫描。例如,如果您使用 LIKE '%ABC%' 搜索名为 title 的 varchar 字段,那么您别无选择,只能让 SQL 扫描每条记录以查看它是否包含这些字符。

    但是,内置的全文搜索实际上会索引您指定要包含在全文索引中的每一列的文本。正是该索引大大加快了您的查询速度。

    不仅如此,全文搜索还提供了 LIKE 运算符无法提供的一些很酷的功能。它不像谷歌那样复杂,但它能够搜索词根的替代版本。但我最喜欢的功能之一是排名功能,它可以返回一个额外的值来指示相关性,然后您可以使用该值对结果进行排序。要使用该功能查看 FREETEXTTABLECONTAINSTABLE 函数。

    更多资源:

    【讨论】:

      【解决方案2】:

      以下应该可以解决问题。我不能说 let kwa = ... 部分是否真的有效,但是需要类似的东西才能使关键字数组在上下文中可用SQL 服务器。我已经有一段时间没有使用 LINQ to SQL(我已经使用 LINQ to Entities 4.0 和 nHibernate 有一段时间了,它们有一组不同的功能)。您可能需要调整该部分以使其正常工作,但总体原则是合理的:

      public List<SearchResult> Search(string keywords)
      {    
        var searcResults = from bp in db.BlogPosts
                           let kwa = keywords.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
                           where kwa.Any(kw => bp.Text.Contains(kw) || bp.Title.Contains(kw))
                           select new SearchResult
                           {
                              PostTitle = bp.Title,
                              BlogPostID = bp.BlogPostID,
                              Test = bp.Text
                           };
      
        return searchResults.ToList();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        • 2017-06-08
        • 1970-01-01
        相关资源
        最近更新 更多