搜索字符串中的每个单词

时间:2017-04-05 13:21:01

标签: c# linq

我仍然试图让我的脑袋围绕着LINQ及其功能。

我正在尝试构建搜索。例如,我想返回与搜索字符串匹配的结果(我们称之为搜索字词)。例如,在数据库中,我们有以下结果:

ID    ItemNum    CategoryType
1     2737       Full Length Dresses
2     5353       Full Length Dresses

如果某人搜索了#34; Full Dresses",我希望能够返回上述两个结果。但是,使用Contains不起作用。搜索"全长连衣裙"确实有效。我猜测我需要以某种方式将搜索字符串拆分成数组,然后使用数组中的每个项目进行搜索,但我不确定如何执行此操作。

var results = db.Products.Where(p => p.CategoryType.Contains(searchString)).Select(p => p).Distinct();

感谢。

6 个答案:

答案 0 :(得分:2)

如果您的基础数据存储区是Sql Server,并且条款的顺序很重要,那么您可以使用:

searchString = searchString.Replace(" ", "%");
var results = db.Products.Where(p => SqlFunctions.PatIndex(searchString , p.CategoryType) > 0).Distinct();

否则您可能需要分开条款并单独处理:

var terms = searchTerms.Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var results = db.Products.Where(p => terms.All(x => p.CategoryType.Contains(x))).Distinct()

并且,如果您希望它返回任何匹配(因此,OR而不是AND),请使用Any linq函数而不是All linq函数:

var terms = searchTerms.Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var results = db.Products.Where(p => terms.Any(x => p.CategoryType.Contains(x))).Distinct()

答案 1 :(得分:0)

由于您的LINQ将被转发到底层数据库以供执行,因此许多.NET函数不能直接在查询中使用(因为在数据库级别没有规范的等价物)。您应首先将所有类别提取到内存中,然后使用完整的LINQ-to-Objects来过滤结果:

这应该这样做:

var Matches = results.Where(p => searchString.Split(' ').Any(x => p.Contains(x)).Distinct();

我假设搜索字符串中的单词将用空格分隔。如果还有其他标点符号,则可以在上面的数组中添加所有标点符号。如果space是您唯一的分隔符,则上面的第二行可以简化为:

SELECT CONVERT(VARCHAR(10), GETDATE(), 103) AS [DD/MM/YYYY]

答案 2 :(得分:0)

我会用一些用户友好的东西扩展它:

public int onStartCommand(Intent intent, int flags, int startId) {
    // read extra from activity
    String data = intent.getStringExtra("extra");
    // your firebase code here
    return super.onStartCommand(intent, flags, startId);
}

答案 3 :(得分:0)

试试这个(当然这将只适用于LINQ to SQL):

string[] str = searchString.split();
string newSearchString ="%";

foreach (string item in str)
{
   newSearchString += item + "%"; 
}

var results = from p in db.products
              where SqlMethods.Like(p.CategoryType , newSearchString  )
              select p;

答案 4 :(得分:0)

    IEnumerable<string> values = "Full,Dresses".Split(',');
var matchingRows = from row in datatable.AsEnumerable()
                   join value in values
                   on row.Field<string>(CategoryType) equals value
                   select row;
DataTable tblResult = matchingRows.CopyToDataTable();

答案 5 :(得分:0)

将此作为答案发布,评论时间过长。

请记住,如果表格很大,这可能会产生糟糕的表现,因为即使您在CategoryType上创建常规索引,它也永远不会被使用(除非您对简单表达感到满意)从“你不是的搜索类型”开始。

我不知道您使用的是哪种RDBMS,但如果可用,我会调查全文搜索的使用情况。如果您使用的是SQL Server,它看起来像you can have Linq use a full-text index

如果你在代码like @dotNET suggested中搜索它会变得更好,你也有机会实现更高级的东西(查看Levenshtein距离算法,这将允许你提供模糊的字符串匹配),但是已经完整文本搜索是你可能想要记住的事情,因为如果你最终拥有数百万行,这种方法可能无法很好地扩展。