0

I have an application where I am taking a large number of 'product names' input by a user and retrieving some information about each product. The problem is, the user may input a partial name or even a wrong name, so I want to return the closest matches for further selection.

Essentially if product name A exactly matches a record, return that, otherwise return any contains matches. Otherwise return null.

I have done this with three separate statements, and I was wondering if there was a more efficient way to do this. I am using LINQ to EF, but I materialize the products to a list first for performance reasons.

productNames is a List of product names (input by the user). products is a List of product 'records'



var directMatches = (from s in productNames
                     join p in products on s.ToLower() equals p.name.ToLower() into result
                     from r in result.DefaultIfEmpty()
                     select new {Key = s, Product = r});

var containsMatches = (from d in directMatches
                      from p in products
                      where d.Product == null
                            && p.name.ToLower().Contains(d.Key)
                      select new { d.Key, Product = p });

var matches = from d in directMatches
              join c in containsMatches on d.Key equals c.Key into result
              from r in result.DefaultIfEmpty()
              select new {d.Key, Product = d.Product ??  (r != null ? r.Product: null) };
4

1 回答 1

1

如果您在内存中有一个中小型列表,请查看LiquidMetal,对于语音匹配,Soundex算法对最接近的匹配进行排名。

如果您使用的是 SQL Server,请查看Stack Overflow 使用的Full-Text Search 。否则,就是我实现基于关键字的搜索的方式。

于 2010-12-23T13:57:30.860 回答