新闻中心
Lar*el 8 数据库多词模糊搜索优化指南

本文旨在解决 lar*el 8 中使用 eloquent orm 进行多词模糊搜索时遇到的挑战,特别是当搜索词包含多个单词(如姓名和姓氏)时无法正确匹配的问题。通过介绍一种将搜索短语分词并结合 `orwhere` 语句进行动态查询的策略,实现更灵活、准确的数据库搜索功能。
理解多词搜索的挑战
在 Lar*el 中,当我们需要在多个数据库字段中执行模糊搜索时,通常会使用 where 或 orWhere 结合 LIKE 操作符。例如,以下代码片段展示了在多个字段中搜索单个关键词的常见做法:
$query = Immovable::query()
->leftJoin('streets', 'streets.gus_id', '=', 'immovables.street_gus_id')
->select(
'immovables.id',
'immovables.street_gus_id',
'immovables.building_number',
'immovables.apartment_number',
'streets.name as street_name'
);
if (request()->has('search')) {
$searchTerm = "%" . request()->search['value'] . "%";
$query->where('streets.name', 'like', $searchTerm)
->orWhere('immovables.community', 'like', $searchTerm)
// ... 其他 orWhere 条件
->orWhere('immovables.name', 'like', $searchTerm)
->orWhere('immovables.surname', 'like', $searchTerm);
}
$results = $query->get();这种方法对于单个单词的搜索(例如,搜索 "Karol" 或 "Krawczyk")是有效的。然而,当用户输入包含多个单词的搜索短语(例如 "Karol Krawczyk")时,上述代码会将其作为一个整体进行匹配。这意味着数据库将尝试查找一个字段中同时包含 "Karol Krawczyk" 整个字符串的记录。如果 "Karol" 在 immovables.name 字段,而 "Krawczyk" 在 immovables.surname 字段,或者它们分散在不同的字段中,那么这种整体匹配的方式将无法返回任何结果,从而导致搜索失败。
要解决这个问题,我们需要将用户输入的搜索短语拆分成独立的单词,并对每个单词在所有目标字段中执行独立的模糊匹配。
解决方案:分词与动态查询
为了实现更灵活的多词搜索,我们可以采取以下策略:
美图云修
商业级AI影像处理工具
50
查看详情
- 分词处理: 将用户输入的搜索短语(例如 "Karol Krawczyk")按照空格或其他分隔符拆分成独立的单词("Karol", "Krawczyk")。
- 动态构建查询: 遍历这些拆分后的单词,对每个单词在所有需要搜索的字段中应用 LIKE 操作符。关键在于,对于每个单词,我们都使用 orWhere 来连接其在不同字段上的匹配条件。
示例代码
以下是优化后的 Lar*el 查询代码,它演示了如何实现上述策略:
use Illuminate\Http\Request;
use App\Models\Immovable; // 假设您的模型名为 Immovable
class SearchController extends Controller
{
public function search(Request $request)
{
$query = Immovable::query()
->leftJoin('streets', 'streets.gus_id', '=', 'immovables.street_gus_id')
->select(
'immovables.id',
'immovables.street_gus_id',
'immovables.building_number',
'immovables.apartment_number',
'streets.name as street_name'
);
if ($request->has('search') && !empty($request->search['value'])) {
// 将搜索值按空格拆分成多个单词
$s
earches = explode(" ", $request->search['value']);
// 使用一个闭包来分组所有的 OR 条件,确保逻辑清晰
$query->where(function ($q) use ($searches) {
foreach ($searches as $search) {
$searchTerm = "%" . $search . "%"; // 为每个单词构建模糊匹配字符串
// 对每个单词在所有相关字段中执行 OR 匹配
$q->orWhere('streets.name', 'like', $searchTerm);
$q->orWhere('immovables.community', 'like', $searchTerm);
$q->orWhere('immovables.city', 'like', $searchTerm);
$q->orWhere('immovables.building_number', 'like', $searchTerm);
$q->orWhere('immovables.granted_comments', 'like', $searchTerm);
$q->orWhere('immovables.inspections', 'like', $searchTerm);
$q->orWhere('immovables.oze_installations', 'like', $searchTerm);
$q->orWhere('immovables.pesel', 'like', $searchTerm);
$q->orWhere('immovables.name', 'like', $searchTerm);
$q->orWhere('immovables.surname', 'like', $searchTerm);
$q->orWhere('immovables.email1', 'like', $searchTerm);
$q->orWhere('immovables.email2', 'like', $searchTerm);
$q->orWhere('immovables.email3', 'like', $searchTerm);
$q->orWhere('immovables.phone1', 'like', $searchTerm);
$q->orWhere('immovables.phone2', 'like', $searchTerm);
$q->orWhere('immovables.phone3', 'like', $searchTerm);
$q->orWhere('immovables.description', 'like', $searchTerm);
}
});
}
$results = $query->get();
return view('your.view', compact('results')); // 假设您将结果传递给视图
}
}代码解析
- explode(" ", $request->search['value']): 这行代码将用户输入的搜索字符串 $request->search['value'] 按照空格进行分割,生成一个包含所有独立单词的数组 $searches。例如,"Karol Krawczyk" 将变为 ['Karol', 'Krawczyk']。
- $query->where(function ($q) use ($searches) { ... }): 这是一个关键的优化。通过使用 where 闭包,我们将所有针对搜索词的 OR 条件封装在一个独立的逻辑组中。这在 SQL 中通常会生成类似 WHERE (condition1 OR condition2 OR ...) 的语句,确保了搜索逻辑的正确优先级,避免与其他潜在的 AND 条件发生冲突。
- foreach ($searches as $search): 循环遍历每个拆分后的单词。
- $searchTerm = "%" . $search . "%": 为当前循环的单词构建一个 LIKE 匹配字符串,例如 "%Karol%"。
-
$q->orWhere('column_name', 'like', $searchTerm): 对于每个单词 $search,我们遍历所有需要搜索的字段,并使用 orWhere 将它们连接起来。这意味着只要任何一个字段包含当前单词,该记录就会被匹配。
- 例如,如果搜索词是 "Karol Krawczyk",循环将首先处理 "Karol"。此时,查询会添加一系列 orWhere 条件,查找任何字段中包含 "Karol" 的记录。
- 接着,循环处理 "Krawczyk"。此时,又会添加一系列 orWhere 条件,查找任何字段中包含 "Krawczyk" 的记录。
- 最终生成的 SQL 查询将是一个大的 OR 逻辑块,例如: WHERE ( (streets.name LIKE '%Karol%' OR immovables.community LIKE '%Karol%' OR ... OR immovables.surname LIKE '%Karol%') OR (streets.name LIKE '%Krawczyk%' OR immovables.community LIKE '%Krawczyk%' OR ... OR immovables.surname LIKE '%Krawczyk%') )
- 这样,无论 "Karol" 和 "Krawczyk" 出现在哪个字段,或者是否同时出现,只要满足任一条件,记录都会被检索出来。
注意事项
-
性能考量: 这种方法在搜索字段较多且数据量庞大时,可能会导致性能下降。因为 LIKE %...% 操作符通常无法有效利用索引,尤其是前导通配符 (%)。
-
优化建议: 对于高并发或大数据量的搜索需求,可以考虑使用专门的全文搜索解决方案,如:
- MySQL Full-Text Search: 如果您的数据库是 MySQL,可以为相关字段创建全文索引。
- Elasticsearch 或 Solr: 专业的搜索服务,提供强大的搜索功能、分词、相关性排序等。
- Lar*el Scout: Lar*el 提供的一个驱动,可以轻松地将 Eloquent 模型与 Algolia、Elasticsearch 等搜索服务集成。
-
优化建议: 对于高并发或大数据量的搜索需求,可以考虑使用专门的全文搜索解决方案,如:
-
搜索词清理: 在实际应用中,建议对用户输入的搜索词进行额外的清理,例如:
- trim():去除首尾空格。
- mb_strtolower():转换为小写(如果搜索不区分大小写)。
- 去除多余的空格(例如,将 "Karol Krawczyk" 变为 "Karol Krawczyk")。
- 用户体验: 结合前端技术,可以提供搜索建议、实时搜索、搜索结果高亮等功能,进一步提升用户体验。
- SQL 注入: Lar*el Eloquent ORM 已经内置了对 SQL 注入的防护,通过参数绑定来处理所有用户输入。因此,只要您通过 Eloquent 的方法构建查询,就无需担心 SQL 注入问题。
总结
通过将用户输入的搜索短语进行分词,并结合 Lar*el Eloquent 的 orWhere 闭包和循环结构,我们可以有效地实现多词模糊搜索功能。这种方法解决了单一 LIKE 匹配无法处理多单词搜索的局限性,使得搜索结果更加灵活和符合用户预期。然而,对于大规模应用,仍需权衡性能,并考虑引入更专业的全文搜索解决方案。
以上就是Lar*el 8 数据库多词模糊搜索优化指南的详细内容,更多请关注其它相关文章!
# laravel
# 前端
# go
# mysql
# 营销推广新闻
# 保山推广网站
# 云南学seo培训
# 成都游戏推广招聘网站
# 化妆品网站建设
# seo陶宝客是什么
# 金华全网营销推广培训
# 庐江网站推广公司多少钱
# 什么是seo教程口碑
# 出租公寓营销推广方案
# 搜索结果
# 怎么做
# 我们可以
# 搜索功能
# 您的
# 遍历
# 美图
# 转换为
# 多个
# 关键词
# ai
# app
# 大数据
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
火狐浏览器占用内存高卡顿怎么办 火狐浏览器性能优化设置技巧
Yandex官网搜索引擎免登录_俄罗斯Yandex一键直达入口
mc.js官网登录入口 mc.js官方登录入口最新版
怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法
顺丰快递查单号物流信息 顺丰快递小程序查询入口
在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南
c++如何实现单例设计模式_c++线程安全的单例模式写法
Win11怎么设置鼠标指针速度_Win11提高鼠标指针精确度选项
如何使用Node.js csv 包按条件移除含空字段的CSV记录
谷歌推RCS信息存档功能:公司可监控员工私密信息!
在WordPress中通过REST API获取BasicAuth保护的远程文章
Python模块化编程:有效管理依赖与避免循环引用
海量存储:机器视觉智能化的核心基石
qq邮箱日历功能怎么用_创建日程与会议邀请的技巧
网易大神账号申诉需要多久_网易大神账号申诉流程说明
必由学在线入口 必由学网页版快速登录入口
中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】
小米14应用无法联网原因分析_小米14网络权限修复
AWS EC2实例间SQL Server连接超时:安全组配置与故障排除指南
没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享
如何在CSS中使用浮动制作导航栏_float实现水平菜单
外媒分析《GTA6》定价:卖100美元可以但真没必要!
京东单号查询入口_京东快递订单追踪入口
C++如何比较两个字符串_C++ string compare函数与操作符对比
Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议
J*aScriptWebpack优化_J*aScript构建工具实战
Fabric Mod开发:在1.19.3+版本中正确添加自定义物品并管理物品组
从OpenAI API响应中高效提取生成文本
Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐
“在文档元素之后找到了标记”是什么错误? 检查并修复XML中多个根元素的3个方法
解决 MongoDB 聚合查询中对象数组 _id 匹配问题
汽水音乐在线版入口_汽水音乐网页播放手册
Golang如何优雅处理error_Golang error处理最佳实践总结
不同用户不同价格! 索尼开启账户个性化定价测试
电脑屏幕颜色不舒服怎么办_Windows夜间模式与色彩校准教程【护眼技巧】
PS5 Pro有点优势但不多! 《燕云十六声》PS5平台与PC性能画面对比
Animex动漫社网入口地址 Animex动漫社网正版在线入口
Go语言中动态执行代码字符串的策略与实践
蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版
零跑汽车11月交付量达70327台 实现连续9个月正增长
ExcelARRAYTOTEXT函数怎么自定义分隔符输出数组文本_ARRAYTOTEXT实现动态生成SQL语句
QQ官网正版登录链接 QQ在线登录入口最新
微信网页版官方入口直达 微信网页版网页版登录使用方法
Django通过AJAX异步上传图片并保存至模型的完整指南
荣耀Play7T运行卡顿解决_荣耀Play7T性能优化
抖音创作助手登录入口_抖音创作辅助工具官网直达
必由学官方网站入口 必由学学生教师共用登录通道
1688商家版怎样分析买家画像精准供货_1688商家版分析买家画像精准供货【供货策略】
HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全
Golang如何处理RPC请求负载均衡_Golang RPC请求负载均衡策略与实践


2025-11-26
浏览次数:次
返回列表
earches = explode(" ", $request->search['value']);
// 使用一个闭包来分组所有的 OR 条件,确保逻辑清晰
$query->where(function ($q) use ($searches) {
foreach ($searches as $search) {
$searchTerm = "%" . $search . "%"; // 为每个单词构建模糊匹配字符串
// 对每个单词在所有相关字段中执行 OR 匹配
$q->orWhere('streets.name', 'like', $searchTerm);
$q->orWhere('immovables.community', 'like', $searchTerm);
$q->orWhere('immovables.city', 'like', $searchTerm);
$q->orWhere('immovables.building_number', 'like', $searchTerm);
$q->orWhere('immovables.granted_comments', 'like', $searchTerm);
$q->orWhere('immovables.inspections', 'like', $searchTerm);
$q->orWhere('immovables.oze_installations', 'like', $searchTerm);
$q->orWhere('immovables.pesel', 'like', $searchTerm);
$q->orWhere('immovables.name', 'like', $searchTerm);
$q->orWhere('immovables.surname', 'like', $searchTerm);
$q->orWhere('immovables.email1', 'like', $searchTerm);
$q->orWhere('immovables.email2', 'like', $searchTerm);
$q->orWhere('immovables.email3', 'like', $searchTerm);
$q->orWhere('immovables.phone1', 'like', $searchTerm);
$q->orWhere('immovables.phone2', 'like', $searchTerm);
$q->orWhere('immovables.phone3', 'like', $searchTerm);
$q->orWhere('immovables.description', 'like', $searchTerm);
}
});
}
$results = $query->get();
return view('your.view', compact('results')); // 假设您将结果传递给视图
}
}