按搜索字符串中的每个单词搜索名称
Posted
技术标签:
【中文标题】按搜索字符串中的每个单词搜索名称【英文标题】:Searching names by each word in search string 【发布时间】:2021-10-06 19:38:27 【问题描述】:我正在尝试在我的 ASP.NET MVC 网站中构建搜索。 例如,我想返回与搜索字符串中任何关键字匹配的项目匹配的产品。例如,我有一些产品,例如,
DC 12V RGB 5050 5M LED灯条 RGB 5050 LED 5 米灯带套件,带 24 键红外遥控器 LED 灯条 DC 12V 44 键红外遥控 RGB 控制器目前,如果我搜索“rgb strip”,我不会从搜索中得到任何结果。 如果我搜索“rgb strip”,我需要从搜索文本。在当前功能中,如果我搜索“rgb”,它会返回以上 3 种产品。我需要实现一种搜索产品的机制,其中包含产品名称中的每个单词。但我不知道该怎么做。可以请任何人帮助我吗? 谢谢。
当前搜索功能:
public List<Product> SearchProducts(List<int> categoryIDs, string searchTerm, decimal? from, decimal? to, string sortby, int? pageNo, int recordSize, bool activeOnly, out int count, int? stockCheckCount = null)
var context = DataContextHelper.GetNewContext();
var products = context.Products
.Where(x => !x.IsDeleted && (!activeOnly || x.IsActive) && !x.Category.IsDeleted)
.AsQueryable();
if (!string.IsNullOrEmpty(searchTerm))
products = context.ProductRecords
.Where(x => !x.IsDeleted && x.Name.ToLower().Contains(searchTerm.ToLower()))
.Select(x => x.Product)
.Where(x => !x.IsDeleted && (!activeOnly || x.IsActive) && !x.Category.IsDeleted)
.AsQueryable();
if (categoryIDs != null && categoryIDs.Count > 0)
products = products.Where(x => categoryIDs.Contains(x.CategoryID));
基于@Rashik Hasnat 的回答,
我在此处访问 Name 属性时遇到问题,因为 Name 属性继承自 ProductRecords 模型,但表达式属性映射到 Products 模型。你能帮忙解决这个问题吗?谢谢。
【问题讨论】:
【参考方案1】:我更喜欢在这里使用正则表达式,但不幸的是,在 LINQ to Entities 中使用它有一个限制。因此你可以使用DbFunctions.Like():
if (!string.IsNullOrEmpty(searchTerm))
// Build the pattern for the Like() method
var pattern = "%" + String.Join("%", searchTerm.Split(' ')) + "%";
products = context.ProductRecords
.Where(x => !x.IsDeleted && DbFunctions.Like(x.Name, pattern))
.Select(x => x.Product)
.Where(x => !x.IsDeleted && (!activeOnly || x.IsActive) && !x.Category.IsDeleted)
.AsQueryable();
【讨论】:
【参考方案2】:你可以这样做:
-
将搜索文本拆分为单词
将linq表达式的逻辑保存在一个变量中(字符串匹配部分除外)
为搜索词中的每个单词添加包含表达式。
代码如下:
if (!string.IsNullOrEmpty(searchTerm))
//split each word of the search string
var searchWordList = searchTerm.Split(" ");
var expression = context.ProductRecords
.Where(x => !x.IsDeleted && x.Name.ToLower().Contains(searchTerm.ToLower())).Select(x => x.Product)
.Where(x => !x.IsDeleted && (!activeOnly || x.IsActive) && !x.Category.IsDeleted);
foreach (var word in searchWordList)
// Add a condition for each word to be present
expression = expression
.Where(x => x.Name.ToLower().Contains(word.ToLower()));
products = expression
.AsQueryable();
【讨论】:
非常感谢您的解决方案,但我遇到了一个问题。我已经更新了问题中的屏幕截图。您能帮我们解决问题吗?以上是关于按搜索字符串中的每个单词搜索名称的主要内容,如果未能解决你的问题,请参考以下文章