按搜索字符串中的每个单词搜索名称

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();
        

【讨论】:

非常感谢您的解决方案,但我遇到了一个问题。我已经更新了问题中的屏幕截图。您能帮我们解决问题吗?

以上是关于按搜索字符串中的每个单词搜索名称的主要内容,如果未能解决你的问题,请参考以下文章

执行查询搜索以匹配字符而不是确切的单词。

Java中的字符串搜索算法

从搜索文档中查找最小片段的算法?

Django 搜索包含空格的字符串

搜索字符串中的单个单词

如何搜索字符串以查看我是不是可以拼写单词