sql-server - Entity Framework 复杂搜索功能
问题描述
我正在使用Entity Framework
a SQL Express database
,现在我必须创建一个搜索功能来根据在文本框中输入的值来查找用户,最终用户可以在其中输入他想要的所有内容(如谷歌)
为此创建搜索功能的最佳方法是什么。输入应搜索所有列。
例如,我有 4 列。firstname
, lastname
, address
, emailaddress
.
当有人在搜索框中键入时foo
,需要在所有列中搜索包含的所有内容foo
。
所以我想我可以做类似的事情
context.Users.Where(u =>
u.Firstname.Contains('foo') ||
u.Lastname.Contains('foo') ||
u.Address.Contains('foo') ||
u.EmailAddress.Contains('foo')
);
但是...最终用户也可以输入foo bar
. 然后搜索值中的空间成为and
要求。所以应该搜索所有列,例如firstname
可能是foo
并且lastname
可能是bar
。
我认为这对于 Linq 查询来说太复杂了?
也许我应该创建一个搜索索引并将所有列组合到搜索索引中,例如:
[userId] [indexedValue]
indexedValue
[ firstname + " "+ lastname + " "+ address +" " + emailaddress
]在哪里。
然后首先根据空格分割搜索值,然后搜索搜索值中包含所有单词的列。这是一个好方法吗?
解决方案
任何项目的第一步都是管理期望。找到满足业务需求的最小可行解决方案并进行开发。随着商业价值的证明,扩展它。提供真正灵活和智能感觉的搜索功能当然会让企业感到高兴,但它通常无法做到他们期望它做的事情,或者执行他们需要的标准,而更简单的解决方案可以满足他们的需要,更简单的开发和更快的执行。
如果这代表了最小可行的解决方案,并且您想要基于空格“和”条件:
public IQueryable<User> SearchUser(string criteria)
{
if(string.IsNullOrEmpty(criteria))
return new List<User>().AsQueryable();
var criteriaValues = criteria.Split(' ');
var query = context.Users.AsQueryable();
foreach(var value in criteriaValues)
{
query = query.Where(u =>
|| u.Firstname.Contains(value)
|| u.Lastname.Contains(value)
|| u.Address.Contains(value)
|| u.EmailAddress.Contains(value));
}
return query;
}
尝试索引组合值的问题在于,不能保证对于像“foo bar”这样的值,“foo”代表名字,“bar”代表姓氏,或者“foo”代表完整的 vs . 部分价值。您还需要考虑去掉逗号和其他标点符号,因为有人可能会键入“smith, john”
当涉及到搜索时,可能需要执行更多的模式匹配来检测用户可能正在搜索的内容。例如,像“smith”这样的单个词可能会搜索名字或姓氏的完全匹配并显示结果。如果没有匹配,则执行Contains
搜索。如果它包含 2 个单词,则 First & last name 匹配搜索假设“first last”与“last, first” 如果该值具有“@”符号,则默认为电子邮件地址搜索,如果它以数字开头,然后是地址搜索。每个检测到的搜索选项都可以进行第一次搜索(期望更精确的值),然后如果返回为空,则进行第二次更广泛的搜索假设。甚至可以通过更广泛的检查进行第 3 次和第 4 次搜索。当显示结果时,如果返回的结果没有返回用户期望的结果,则可能会提供一个“更多结果...”按钮来触发第二次、第三次、第四次等通过搜索。
关于搜索的想法是:尝试执行最典型、最窄的预期搜索,并允许用户根据需要扩大搜索范围。目标是尽早尝试和“命中”最相关的结果,帮助塑造用户输入标准的方式,然后根据用户反馈进行调整以更好地执行,而不是尝试编写查询以返回尽可能多的命中。目标是帮助用户在结果的第一页上找到他们正在寻找的内容。无论哪种方式,构建有用的搜索都会增加利用新的 3rd 方库的复杂性。首先确定是否确实需要该功能。
推荐阅读
- c# - 如何在不下载的情况下读取位于 Azure 容器中的压缩 txt 文件(blob)?
- javascript - 如何在 HTML 元素(基于 JSON)中找到负责更改数据的 javascript 代码?
- flutter - Dart,后面带感叹号的标识符
- dart - Flutter 提供者,关于 Dart 语法的问题
- solr - 在 Zookeeper 3.4.5 上以云模式使用 Solr 8.7 是否存在任何可能的问题
- github-actions - 在索引列表表达式中设置 GitHub 操作输出变量
- ios - 使用 SecKeyGeneratePair 生成密钥对时,标志 kSecAttrAccessControl 是否对公钥有影响?
- python - 将多个 DataFrame 系列添加到同一 DataFrame 中的新系列
- visual-studio-code - 仅在 VSCode 编辑器中显示相关的智能感知建议
- java - 如何将 css 文件添加到 Spring Boot 应用程序(Thymeleaf)分页