代码之家  ›  专栏  ›  技术社区  ›  griegs

使用LINQ搜索关键字

  •  3
  • griegs  · 技术社区  · 14 年前

    如果我有一个包含say a title的文本字段,并且我有一个关键字列表,那么我如何搜索标题,检查标题中关键字的(n)个数?

    因此,如果我的标题是“烤鸡肉、培根和韭菜派”,并且用户搜索“鸡肉、培根和萝卜”,我想返回上述配方。

    本质上,我想说,如果标题包含say 2个或更多的搜索词,那么它被认为是有效的,应该被返回。但如果它只包含1,那么忽略它。

    理想情况下,我希望对它们进行加权,这样列表中出现的术语越多,就越高,但这可能是版本2。:)

    编辑

    我应该在这一点上提到,我希望这个是原生的.NET和C。

    4 回复  |  直到 14 年前
        1
  •  4
  •   Andras Zoltan    14 年前

    好吧,我知道你说过“在林肯做”。假设您正在讨论使用.NET本机字符串并使用Linq to对象,那么我想最明显的解决方案是通过一个处理单词边界的regex分解文本;然后迭代每个与输入短语匹配的结果。

    然而。。。

    从你对“v2”的想法来看,我认为你应该寻找一个更强大、更适合于文本搜索的东西,那么使用 Lucene.Net 文本索引?

    它提供 非常 强大的 非常 快速的全文搜索——并且能够处理布尔规则;别名、词干等等。

    它真的很摇滚。

    更新-因为您在注释中提到了linq to sql

    但是,您也可以在表中使用SQL全文索引,这有一个要点:没有本地的linq-to-sql转换到containstable等子句。

    因此,您可以通过字符串使用动态查询生成,然后将其输入 DataContext.ExecuteQuery<TResult> 成员。如果select返回构造所需实体类型所需的列,它将像一个符咒一样工作。

    或者,当然,您也可以只包装执行此操作的存储过程;)

        2
  •  1
  •   StriplingWarrior    14 年前

    做一个像安德拉斯建议的文本索引可能是你最好的选择。但是要回答这个问题:您可以编写一个方法来定制一个表达式树来表示一个选择器,它为每个匹配的搜索关键字向属性添加1。见下文:

    var entries = new[] { new Entry{ ID = 1,  Title = "Baking a chicken, bacon and leek pie"} }.AsQueryable();
    var search = "chicken bacon turnip";
    var q = entries.Select(GetSelector(search));
    var matches = q.Where(e => e.MatchCount > 1);
    
    public Expression<Func<Entry, EntryMatchCount>> GetSelector(string search)
    {
        var searchWords = search.Split(new[] {' '});
        // Rather than creating the selector explicitly as below, you'll want to
        // write code to generate this expression tree.
        Expression<Func<Entry, EntryMatchCount>> selector = e =>
                new EntryMatchCount
                {
                    ID = e.ID,
                    MatchCount = (e.Title.Contains(searchWords[0]) ? 1 : 0) +
                                (e.Title.Contains(searchWords[1]) ? 1 : 0) +
                                (e.Title.Contains(searchWords[2]) ? 1 : 0)
                };
        return selector;
    }
    
        3
  •  0
  •   Tim Jarvis    14 年前

    如果是我,我会做这样的事情……

    创建一个帮助器类,该类执行两项操作,拆分标题并基于关键字匹配返回分数….

    public static class Helper
    {
    
      public static int GetScore(string Title, params string[] keywords)
      {
        // your routine that calcs a score based on the matchs against the Title.
      }
    }
    
    then you can use a linq statement like....
    
    var matches = from t in GetYourTitles
                  let score = Helper.GetScore(t, keywordlist)
                  where score >= 2
                  orderby score
                  select t;
    
        4
  •  0
  •   RedPanda    14 年前

    aodbDataContext db=new aodbDataContext();

            var fItems = from item in db.Items
                         where SqlMethods.Like(item.Name, l)
                         where cats.Contains(item.ItemType)
                         where item.QL >= minQL
                         where item.QL <= maxQL
                         select item;