本文针对 laravel 8 中使用 `orwhere` 进行多字段、多关键词模糊搜索时遇到的挑战,深入探讨了如何通过分词处理用户输入,并结合 laravel 查询构建器的嵌套 `where` 子句,实现更灵活、准确的搜索逻辑。文章提供了详细的代码示例和性能优化建议,旨在帮助开发者构建高效且用户友好的搜索功能。
在 Laravel 应用中,为数据库模型实现搜索功能是常见的需求。当需要在一个或多个字段中进行模糊匹配时,where('field', 'like', '%keyword%') 或 orWhere('field', 'like', '%keyword%') 是常用的方法。然而,这种简单的模式在处理用户输入多个关键词(例如 "Karol Krawczyk")时,往往会遇到问题。
考虑以下场景:用户希望搜索姓名为 "Karol Krawczyk" 的记录,其中 "Karol" 可能存储在 name 字段,而 "Krawczyk" 存储在 surname 字段。如果直接使用原始的搜索逻辑:
$query->where('immovables.name', 'like', "%Karol Krawczyk%");
$query->orWhere('immovables.surname', 'like', "%Karol Krawczyk%");
// ... 其他字段这样的查询将尝试在 name 或 surname 字段中查找完整的字符串 "Karol Krawczyk"。如果数据库中 name 字段的值是 "Karol",surname 字段的值是 "Krawczyk",则上述查询将无法匹配到任何结果,因为没有一个字段完整包含 "Karol Krawczyk" 这个字符串。这导致了搜索结果不准确或缺失的问题。
要解决上述问题,核心策略在于对用户输入的搜索字符串进行“分词”处理,并将每个分词后的关键词作为独立的搜索条件。具体来说,我们需要将 "Karol Krawczyk" 拆分为 "Karol" 和 "Krawczyk" 两个独立的关键词。然后,对于每个关键词,我们构建一组 OR 条件,使其在所有目标字段中进行模糊匹配。最后,将这些关键词的搜索条件组通过 OR 逻辑连接起来,即:如果任一关键词在任一目标字段中匹配成功,则该记录应被检索。
这种策略能够实现更灵活的模糊搜索,例如,用户输入 "Karol Krawczyk" 时,查询逻辑将变为:
(streets.name LIKE '%
Karol%' OR immovables.name LIKE '%Karol%' OR immovables.surname LIKE '%Karol%' OR ...)OR(streets.name LIKE '%Krawczyk%' OR immovables.name LIKE '%Krawczyk%' OR immovables.surname LIKE '%Krawczyk%' OR ...)
这样,只要 "Karol" 匹配到 name 字段,或者 "Krawczyk" 匹配到 surname 字段(或者其他任何字段),该记录都会被包含在结果中。
在 Laravel 8 中,我们可以利用查询构建器的闭包功能来优雅地实现分词与条件分组。
首先,像往常一样初始化你的 Eloquent 查询,包括任何必要的联接和选择字段:
use Illuminate\Http\Request;
use App\Models\Immovable; // 假设你的模型是 Immovable
class ImmovableController extends Controller
{
public function index(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'
);
// ... 接下来添加搜索条件
}
}接下来是实现多关键词搜索的核心逻辑。我们将检查请求中是否存在 search 参数,然后对搜索值进行分词,并使用嵌套的 where 闭包来构建复杂的 OR 条件组。
if ($request->has('search') && !empty($request->search['value'])) {
// 获取搜索值并按空格分割成关键词数组
$searchTerms = explode(" ", $request->search['value']);
// 过滤掉空字符串,以防用户输入多个空格
$searchTerms = array_filter($searchTerms);
// 如果存在有效的搜索关键词,则构建查询条件
if (!empty($searchTerms)) {
$query->where(function ($subQuery) use ($searchTerms) {
foreach ($searchTerms as $term) {
// 对每个关键词,构建一个 OR 条件组
// 确保每个关键词在任一指定字段中匹配
$subQuery->orWhere(function ($innerSubQuery) use ($term) {
$innerSubQuery->where('streets.name', 'like', "%" . $term . "%")
->orWhere('immovables.community', 'like', "%" . $term . "%")
->orWhere('immovables.city', 'like', "%" . $term . "%")
->orWhere('immovables.building_number', 'like', "%" . $term . "%")
->orWhere('immovables.granted_comments', 'like', "%" . $term . "%")
->orWhere('immovables.inspections', 'like', "%" . $term . "%")
->orWhere('immovables.oze_installations', 'like', "%" . $term . "%")
->orWhere('immovables.pesel', 'like', "%" . $term . "%")
->orWhere('immovables.name', 'like', "%" . $term . "%")
->orWhere('immovables.surname', 'like', "%" . $term . "%")
->orWhere('immovables.email1', 'like', "%" . $term . "%")
->orWhere('immovables.email2', 'like', "%" . $term . "%")
->orWhere('immovables.email3', 'like', "%" . $term . "%")
->orWhere('immovables.phone1', 'like', "%" . $term . "%")
->orWhere('immovables.phone2', 'like', "%" . $term . "%")
->orWhere('immovables.phone3', 'like', "%" . $term . "%")
->orWhere('immovables.description', 'like', "%" . $term . "%");
});
}
});
}
}
// 执行查询并获取结果
$results = $query->get();
return view('your.view', compact('results'));
}
}代码解析:
# word
# laravel
# app
# ai
# 字符串
# 闭包
# function
# 数据库
# 性能优化
# 关键词
# 多个
# 多字
# 搜索功能
# 这是
# 更灵活
# 子句
# 空字符串
# 并将
# 使其
相关文章:
制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?
如何在云虚拟主机上快速搭建个人网站?
简易网站制作视频教程,使用记事本编写一个简单的网页html文件?
建站之星多图banner生成与模板自定义指南
制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?
浅析上传头像示例及其注意事项
制作农业网站的软件,比较好的农业网站推荐一下?
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
已有域名建站全流程解析:网站搭建步骤与建站工具选择
C++中引用和指针有什么区别?(代码说明)
成都网站制作报价公司,成都工业用气开户费用?
宝塔面板如何快速创建新站点?
如何用低价快速搭建高质量网站?
网页设计与网站制作内容,怎样注册网站?
宝塔建站助手安装配置与建站模板使用全流程解析
如何用VPS主机快速搭建个人网站?
兔展官网 在线制作,怎样制作微信请帖?
建站之星备案流程有哪些注意事项?
Swift中switch语句区间和元组模式匹配
网站好制作吗知乎,网站开发好学吗?有什么技巧?
长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?
专业网站设计制作公司,如何制作一个企业网站,建设网站的基本步骤有哪些?
网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?
专业公司网站制作公司,用什么语言做企业网站比较好?
如何解决ASP生成WAP建站中文乱码问题?
如何有效防御Web建站篡改攻击?
如何在宝塔面板中创建新站点?
网站设计制作公司地址,网站建设比较好的公司都有哪些?
重庆市网站制作公司,重庆招聘网站哪个好?
如何在阿里云完成域名注册与建站?
专业网站制作服务公司,有哪些网站可以免费发布招聘信息?
linux top下的 minerd 木马清除方法
网站制作难吗安全吗,做一个网站需要多久时间?
如何通过虚拟主机快速完成网站搭建?
保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?
高防服务器如何保障网站安全无虞?
官网网站制作腾讯审核要多久,联想路由器newifi官网
如何快速搭建虚拟主机网站?新手必看指南
南京做网站制作公司,南京哈发网络有限公司,公司怎么样,做网页美工DIV+CSS待遇怎么样?
如何在自有机房高效搭建专业网站?
英语简历制作免费网站推荐,如何将简历翻译成英文?
临沂网站制作公司有哪些,临沂第四中学官网?
定制建站平台哪家好?企业官网搭建与快速建站方案推荐
高端企业智能建站程序:SEO优化与响应式模板定制开发
太平洋网站制作公司,网络用语太平洋是什么意思?
Android自定义listview布局实现上拉加载下拉刷新功能
如何选择高性价比服务器搭建个人网站?
如何配置WinSCP新建站点的密钥验证步骤?
*请认真填写需求信息,我们会在24小时内与您取得联系。