如何在Laravel Collection中筛选匹配指定条件的医生数据
嘿,我来帮你搞定这个医生筛选的需求!针对你给出的Laravel Collection结构,这里有两种实用的实现方式,根据你的场景选就行:
先看你的示例数据(方便参考)
{ "success": true, "doctor": [ { "id": 1, "name": "Dr. Mayank", "dob": "1975-01-01", "about": "This is description", "status": 1, "rating": 2, "rating_given_by": 1, "alternative_number": "7686876876", "profile_photo": [], "speciality": [ { "id": 3, "name": "Acupuncture", "image": null, "dashboard_flag": 1 }, { "id": 4, "name": "Acupuncturist", "image": null, "dashboard_flag": 1 }, { "id": 1, "name": "Accident and emergency medicine", "image": "<a href=\"http://192.168.16.21/remidify/media/174/detail.png\" rel=\"nofollow noreferrer\">http://192.168.16.21/remidify/media/174/detail.png</a>", "dashboard_flag": 1 } ], "service": [ { "id": 78, "name": "Correction of gummy smile", "cost": "12.00" }, { "id": 77, "name": "Dental aesthetics", "cost": "43.00" } ], "clinics": [ { "id": 1, "name": "akram", "entity_id": 1, "entity_type": "App\\Doctor", "contact_number": "2132132132132", "status": 0, "consultancy_fee": "12.00", "available_today": "No", "owner_name": "Dr. Mayank", "pivot": { "doctor_id": 1, "clinic_id": 1 }, "address": { "id": 1, "address_1": "asdasdasdsa", "address_2": "", "locality": "downtown", "city": "noida", "state": "up", "postal_code": "41561566" }, "speciality": [], "service": [ { "id": 11, "name": "Laminates", "cost": "20.00" }, { "id": 12, "name": "Dental surgery", "cost": "300.00" } ], "clinic_image": [ { "id": 7, "model_id": 1, "model_type": "App\\Clinic", "collection_name": "clinic_image", "file_name": "1494863957588.566162.jpg", "disk": "media", "url": "<a href=\"http://192.168.16.21/remidify/media/7/1494863957588.566162.jpg\" rel=\"nofollow noreferrer\">http://192.168.16.21/remidify/media/7/1494863957588.566162.jpg</a>" } ], "id_image": [ { "id": 8, "model_id": 1, "model_type": "App\\Clinic", "collection_name": "id_image", "file_name": "1494863966218.348877.jpg", "disk": "media", "url": "<a href=\"http://192.168.16.21/remidify/media/8/1494863966218.348877.jpg\" rel=\"nofollow noreferrer\">http://192.168.16.21/remidify/media/8/1494863966218.348877.jpg</a>" } ], "location": { "id": 1, "latitude": 0, "longitude": 0, "entity_id": 1, "entity_type": "App\\Clinic", "created_at": "2017-05-16 03:00:10", "updated_at": "2017-05-16 03:00:10" }, "clinic_timings": [ { "day": "sun", "opens_at": "09:28:00", "closes_at": "21:28:00" } ] } ], "education": [ { "id": 19, "degree": "MBBS", "university": "Univercity", "year": "2017", "entity_id": 1, "entity_type": "App\\Doctor", "created_at": "2017-05-16 05:44:11", "updated_at": "2017-05-16 05:44:11", "location": "Delhi" } ], "experience": [ { "id": 19, "hospital": "Hospital name", "post": "pta ni hai", "from": "1970-01-01", "to": "0000-00-00", "entity_id": 1, "entity_type": "App\\Doctor", "created_at": "2017-05-16 05:44:12", "updated_at": "2017-05-16 05:44:12", "location": "Locations12", "is_currently_working": 1 } ], "registration": { "id": 1, "registration_number": "Reg # 2324324", "registration_year": 1975, "registration_council": "Council", "experience": null, "doctor_id": 1, "created_at": "2017-05-16 02:56:37", "updated_at": "2017-05-16 02:56:37", "adhaar_number": "232131231232", "id_proof": [ { "id": 2, "model_id": 1, "model_type": "App\\DoctorRegistration", "collection_name": "id_proof", "file_name": "1494863680447.329102.jpg", "disk": "media", "url": "<a href=\"http://192.168.16.21/remidify/media/2/1494863680447.329102.jpg\" rel=\"nofollow noreferrer\">http://192.168.16.21/remidify/media/2/1494863680447.329102.jpg</a>" } ], "registration_proof": [ { "id": 3, "model_id": 1, "model_type": "App\\DoctorRegistration", "collection_name": "registration_proof", "file_name": "1494863687436.266846.jpg", "disk": "media", "url": "<a href=\"http://192.168.16.21/remidify/media/3/1494863687436.266846.jpg\" rel=\"nofollow noreferrer\">http://192.168.16.21/remidify/media/3/1494863687436.266846.jpg</a>" } ], "qualification_proof": [ { "id": 4, "model_id": 1, "model_type": "App\\DoctorRegistration", "collection_name": "qualification_proof", "file_name": "1494863695576.803955.jpg", "disk": "media", "url": "<a href=\"http://192.168.16.21/remidify/media/4/1494863695576.803955.jpg\" rel=\"nofollow noreferrer\">http://192.168.16.21/remidify/media/4/1494863695576.803955.jpg</a>" } ] }, "preference": { "availability": 1, "appointment_confirmation_method": "manual", "average_time": 7, "holiday_from": null, "holiday_till": null, "patients_per_hour": null, "preferred_appointment_type": "timeslot", "appointment_frequency": null, "preferred_payment_method": [ { "payment_method": "cash" }, { "payment_method": "online" } ] }, "user": null, "doctor_clinic": [ { "doctor_id": 1, "clinic_id": 1, "consultancy_fee": "12.00", "deleted_at": null, "workdays": [ { "day": "sun", "available": 1, "workhours": [ { "from": "09:28:00", "to": "21:28:00" } ] } ], "service": [] } ] } ] }
方式一:过滤已有的Laravel Collection数据
如果数据已经被拉取到内存中(比如你示例里的JSON转成的Collection),可以用集合的filter方法结合字符串匹配来筛选:
use Illuminate\Support\Str; // 1. 先把JSON转成Collection(如果还没转的话) $jsonString = '上面的JSON内容'; $response = json_decode($jsonString, true); $doctorCollection = collect($response['doctor']); // 2. 定义搜索关键词 $searchTerm = "Acupuncture"; // 替换成你的搜索字符串 // 3. 执行筛选 $filteredDoctors = $doctorCollection->filter(function ($doctor) use ($searchTerm) { // 检查about字段是否包含搜索词(不区分大小写) $matchesAbout = Str::contains(strtolower($doctor['about']), strtolower($searchTerm)); // 检查speciality数组中是否有名称匹配的项 $matchesSpeciality = collect($doctor['speciality'])->some(function ($speciality) use ($searchTerm) { return Str::contains(strtolower($speciality['name']), strtolower($searchTerm)); }); // 满足任意一个条件就保留该医生 return $matchesAbout || $matchesSpeciality; }); // 输出结果(可以转成数组或者直接使用) dd($filteredDoctors->toArray());
代码说明:
- 用
Str::contains并统一转小写,实现不区分大小写的模糊搜索,用户搜acupuncture或Acupuncture都能匹配到 some方法用来检查speciality数组中是否存在至少一个符合条件的项,比循环遍历更简洁
方式二:直接从数据库查询时筛选
如果数据是从数据库获取的,推荐用Eloquent查询构造器直接在数据库层面筛选,性能更优(不用拉取全部数据到内存):
use Illuminate\Support\Facades\DB; $searchTerm = "Acupuncture"; // 假设你的模型是Doctor,并且已经和Speciality建立了关联关系 $filteredDoctors = Doctor::whereRaw('LOWER(about) LIKE ?', ["%".strtolower($searchTerm)."%"]) ->orWhereHas('speciality', function ($query) use ($searchTerm) { $query->whereRaw('LOWER(name) LIKE ?', ["%".strtolower($searchTerm)."%"]); }) ->get();
代码说明:
whereRaw结合LOWER函数实现不区分大小写的模糊搜索(适配MySQL,其他数据库可以调整函数,比如PostgreSQL用LOWER,SQL Server用LOWER)orWhereHas用来查询关联的speciality表,检查是否有名称匹配的专科- 如果不需要不区分大小写,直接用
where('about', 'like', "%{$searchTerm}%")即可
内容的提问来源于stack exchange,提问作者Awadhesh Singh
相关产品推荐
相关产品推荐

