You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel按分类及含子级位置检索Listing的实现问题

解决方案:Laravel中分类与位置的层级筛选优化

1. 模型层添加层级ID获取方法

首先在Category和Location模型中实现递归获取所有子级ID的方法,确保选中父节点时能包含所有下级节点的数据。

Category模型代码:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    // 原有的childrenRecursive关联
    public function childrenRecursive()
    {
        return $this->children()->with('childrenRecursive', 'rListing');
    }

    // 递归获取当前分类及其所有子级的ID
    private function getAllCategoryIds()
    {
        $ids = [$this->id];
        foreach ($this->childrenRecursive as $child) {
            $ids = array_merge($ids, $child->getAllCategoryIds());
        }
        return $ids;
    }

    // 静态方法:通过分类ID获取全层级ID集合
    public static function getHierarchyIds($categoryId)
    {
        $category = self::find($categoryId);
        return $category ? $category->getAllCategoryIds() : [];
    }
}

Location模型代码:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Location extends Model
{
    // 原有的childrenRecursive关联
    public function childrenRecursive()
    {
        return $this->children()->with('childrenRecursive', 'rListing');
    }

    // 递归获取当前位置及其所有子级的ID
    private function getAllLocationIds()
    {
        $ids = [$this->id];
        foreach ($this->childrenRecursive as $child) {
            $ids = array_merge($ids, $child->getAllLocationIds());
        }
        return $ids;
    }

    // 静态方法:通过位置ID获取全层级ID集合
    public static function getHierarchyIds($locationId)
    {
        $location = self::find($locationId);
        return $location ? $location->getAllLocationIds() : [];
    }
}

2. 控制器查询逻辑优化

修改原有的查询代码,使用whereIn替代单一ID匹配,传入全层级ID集合实现批量筛选:

// 初始化查询,提前关联必要表并添加固定条件
$listing_items = DB::table('listings')
    ->join('listing_categories', 'listings.listing_category_id', '=', 'listing_categories.id')
    ->join('listing_locations', 'listings.listing_location_id', '=', 'listing_locations.id')
    ->where('listings.listing_status', 'Active');

// 关键词模糊筛选
if ($request->filled('text')) {
    $listing_items->where('listings.listing_name', 'LIKE', '%' . $request->text . '%');
}

// 分类层级筛选
if ($request->filled('category')) {
    $categoryIds = \App\Models\Category::getHierarchyIds($request->category);
    if (!empty($categoryIds)) {
        $listing_items->whereIn('listings.listing_category_id', $categoryIds);
    }
}

// 位置层级筛选
if ($request->filled('location')) {
    $locationIds = \App\Models\Location::getHierarchyIds($request->location);
    if (!empty($locationIds)) {
        $listing_items->whereIn('listings.listing_location_id', $locationIds);
    }
}

// 选择字段并分页返回
$listing_items = $listing_items->select(
    'listings.*',
    'listing_categories.listing_category_name',
    'listing_categories.listing_category_slug',
    'listing_locations.listing_location_name',
    'listing_locations.listing_location_slug'
)->paginate(4);

3. 性能优化建议(针对大数据量)

如果你的分类/位置层级较深或数据量较大,递归模型方法可能存在性能瓶颈,建议使用数据库原生递归查询(以MySQL为例):

修改模型中的getHierarchyIds方法为:

public static function getHierarchyIds($categoryId)
{
    $ids = DB::select("
        WITH RECURSIVE category_hierarchy AS (
            SELECT id FROM categories WHERE id = ?
            UNION ALL
            SELECT c.id FROM categories c
            JOIN category_hierarchy ch ON c.parent_id = ch.id
        )
        SELECT id FROM category_hierarchy
    ", [$categoryId]);
    
    return array_column($ids, 'id');
}

该方法通过数据库的WITH RECURSIVE语法一次性获取所有层级ID,性能更优。

内容的提问来源于stack exchange,提问作者Tajmmal Hussan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:55:16