构建搜索应用程序的最佳实践?

时间:2009-05-21 13:51:01

标签: asp.net sql-server linq-to-sql search

我将很快启动一个简单的数据存储和搜索项目。基本上,其中一个“将我庞大的Excel电子表格放入数据库,为它构建一个Web GUI,并使其成为可搜索的类型”。

让我烦恼的一件事是当用户输入一些标准时将使用的实际搜索逻辑。我想象一个带有文本字段的搜索界面,以及一些其他过滤工具 - 下拉组合框和复选框等。

虽然这给了我对我可以执行的过滤的非常强大,精细的控制,但我想知道实际执行搜索的想法是什么。我将在这里使用ASP.NET,MS SQL Server和Linq-To-SQL,因此请牢记这些技术。

脱离我的头脑,我想我会做类似的事情:

var results = from s in db.Stuff
              where (s.Prop1.Contains(textFilter) ||
                     s.Prop2.Contains(textFilter) ||
                     s.Prop3.Contains(textFilter)) &&
                     checkbox1.IsChecked ?
                          s.Prop4.ToLower().Equals(combobox1.Text) : true
              select s;

以下是我所知道的:

  • 如有必要,如何进行分组和加入
  • 我可以在各个属性上使用 Contains()方法来生成SQL LIKE 查询
  • 我可以按属性过滤事物,按上面的方式构建我的搜索逻辑。

以下是我的要求:

  • 有没有办法搜索所有属性(不将所有对象都拉入内存 - 我假设这意味着用反射构建每个对象属性的列表,将它们串联起来然后检查出来)?如果没有,这似乎非常麻烦,因为我必须为我可能添加的每个新属性构建新逻辑。上面的 s.Contains(textFilter)之类的东西是理想的。
  • SQL LIKE 查询实际上如何工作?这是我想做的事吗?
  • 是否有实现搜索规则的标准方法,例如完全匹配的引用字符串和 AND OR 等逻辑运算符?如果每个实现它们的应用程序都使用自定义解析逻辑,我会感到惊讶。
  • 我在错误的树上吠叫?我错过了什么吗?

3 个答案:

答案 0 :(得分:2)

我最近必须创建一个类似的评论系统搜索。我所做的是我从注释中创建了一些扩展方法,这些方法允许我传入一个通用的过滤对象。

以下是我使用的示例代码:

这只是一种部分方法而且没有回报但会给你一张我正在做的事情:

public List<oComment> GetComments(oCommentSearch filters)
{

    using (CommentDataContext db = CommentContextFactory.CreateContext())
    {
        var query = from comment in db.COMMENTs.FilterComments(filters)
                    select comment;
    }
}

正如你可以看到COMMENTs我有FilterComments。这是一种扩展方法。这个方法看起来像这样(这是我的整个课程):

public static class CommentExtensions
    {
        public static IQueryable<COMMENT> FilterComments(this IQueryable<COMMENT> Comments, oCommentSearch Filters)
        {
            Filters = CheckFilter(Filters);

            IQueryable<COMMENT> tempResult = Comments;

            if(Filters.Classes.Count() > 0)
            {
                tempResult = from t in tempResult
                             where
                                 Filters.Classes.Contains(t.CLASS_ID)
                             select t;
            }

            if (Filters.Flags.Count() > 0)
            {
                tempResult = from t in tempResult
                             where
                                 Filters.Flags.Contains((int) t.FLAG_ID)
                             select t;
            }

            if (Filters.Types.Count() > 0)
            {
                tempResult = from t in tempResult
                             where
                                 Filters.Types.Contains(t.CommentTypeId)
                             select t;
            }
            return tempResult;
        }

        private static oCommentSearch CheckFilter(oCommentSearch Filters)
        {
            Filters.Classes  = CheckIntArray(Filters.Classes);
            Filters.Flags =  CheckIntArray(Filters.Flags) ;
            Filters.Types =  CheckIntArray(Filters.Types) ;
            return Filters;
        }

        private static int[] CheckIntArray(int[] ArrayToCheck)
        {
            return ArrayToCheck == null || ArrayToCheck.Count() == 0 ? new int[] {} : ArrayToCheck;
        }
    }

这应该让你开始朝着正确的方向前进。

希望这有帮助!

答案 1 :(得分:2)

您没有在您使用的技术列表中提及它,但不要忽略使用Lucene.NET。它搜索得很好,并且很容易设置。基本上,您将文档添加到索引,Lucene有效地管理索引。这样,您可以搜索索引,而不是逐个加载文档并查看其属性。

答案 2 :(得分:1)

  

有没有办法搜索所有属性(不将所有对象都拉入内存 - 我假设这意味着用反射构建每个对象属性的列表,对它们进行字符串化,然后检查出来)?如果没有,这似乎非常麻烦,因为我必须为我可能添加的每个新属性构建新逻辑。像上面的s.Contains(textFilter)这样的东西是理想的。

我们正在使用MsSql全文搜索功能。