如果我有一个包含标题的文本字段并且我有一个关键字列表,我如何在标题中搜索(n)个标题中的关键字?
因此,如果我的标题是“烤鸡肉,培根和韭菜馅饼”,并且用户搜索“鸡肉培根萝卜”,我想退回上述食谱。
基本上我想说的是,如果标题包含2个或更多的搜索词,那么它被认为是有效的,应该返回。但如果它只包含1则忽略它。
理想情况下,我希望他们加权,以便列表中出现的条款越多,但可能是版本2. :)
修改
我现在应该提一下,我希望这是原生的.net和c#。
答案 0 :(得分:4)
好的,我知道你说'在Linq做'。虽然你正在谈论使用.Net本地字符串并使用Linq to Objects进行操作,但我想最明显的解决方案是通过正在处理字边界的正则表达式分解文本;然后迭代每个与输入短语匹配的结果。
...然而
根据你对'v2'的想法判断,我认为你应该看一些更强大的东西,并围绕文本搜索 - 那么如何使用Lucene.Net文本索引?
它提供非常强大的 非常 快速全文搜索 - 并且能够处理布尔规则;别名,词干,所有这些东西。
它确实摇滚。
更新 - 由于您在评论中提到了Linq to Sql
您还可以在表上使用SQL全文索引,但有一个问题:没有本地Linq To Sql转换为CONTAINSTABLE等人的条款。
因此,您可以通过字符串使用动态查询生成,然后将其提供给DataContext.ExecuteQuery<TResult>
成员。如果select返回构造所需实体类型所需的列,它将像魅力一样工作。
或者,当然,您可以只包装执行它的存储过程;)
答案 1 :(得分:1)
做像安德拉斯这样的文字索引建议可能是你最好的选择。但回答这个问题:您可以编写一个方法来自定义构建表达式树来表示一个选择器,该选择器为每个匹配的搜索关键字的属性添加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;
}
答案 2 :(得分:0)
如果是我,我会简单地做这样的事情......
创建一个辅助类,它可以完成两件事,分割标题并根据关键字匹配返回一个分数....
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;
答案 3 :(得分:0)
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;