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

Laravel Collection按单个语言维度分组统计及内部排序方案咨询

解决方案:按单个语言维度统计并排序

我明白你的需求——你需要统计每个单独语言(比如en、ar)在所有用户中的出现次数,而不是按整个languages JSON字符串分组。这里有两种靠谱的解决方案,你可以根据场景选择:

方法一:利用Laravel Collection处理(推荐,简单直接)

既然你已经有了Illuminate\Support\Collection实例,直接在内存中处理是最快捷的方式,不需要依赖数据库的JSON功能版本:

// 假设你的Collection实例是$userCollection
$languageStats = $userCollection
    // 遍历每个用户,解析JSON并提取所有语言的键(比如en、cy)
    ->flatMap(function ($user) {
        $languages = json_decode($user->languages, true);
        // 返回语言键数组,flatMap会自动把所有数组合并成一个扁平数组
        return array_keys($languages);
    })
    // 统计每个语言的出现次数
    ->countBy()
    // 按出现次数降序排序(升序用sortAsc())
    ->sortDesc();

代码解释:

  • flatMap():遍历集合中的每个用户,解析languages JSON字符串为关联数组,然后提取所有语言的键(因为我们只需要统计语言出现次数,不需要关注熟练度),最后把所有用户的语言键合并成一个单一数组。
  • countBy():自动统计数组中每个语言的出现次数,返回一个键为语言代码、值为次数的集合。
  • sortDesc():按次数从高到低排序,方便查看热门语言。

执行后你会得到类似这样的结果:

Illuminate\Support\Collection {#3272
  #items: array:8 [
    "en" => 66
    "cy" => 24
    "ar" => 66
    "eo" => 66
    // ...其他语言的统计结果
  ]
}

方法二:数据库层面处理(适合大数据量场景)

如果你的数据量非常大(比如上万条),在数据库层面展开JSON并统计性能会更好。不过需要注意数据库版本:

MySQL 8.0.4+ 版本

利用JSON_TABLE函数展开JSON对象的键:

$languageStats = User::whereIn('id', $services_id)
    ->selectRaw('lang, COUNT(*) as occurrence_count')
    ->fromSub(function ($query) use ($services_id) {
        $query->selectRaw('JSON_TABLE(
            user_info->>"$.languages",
            "$.*" COLUMNS (lang VARCHAR(50) PATH "$.key")
        ) AS langs')
        ->from('users')
        ->whereIn('id', $services_id);
    }, 'user_languages')
    ->groupBy('lang')
    ->orderBy('occurrence_count', 'desc')
    ->get();

PostgreSQL 版本

利用jsonb_each_text函数拆分JSON对象:

$languageStats = User::whereIn('id', $services_id)
    ->selectRaw('lang, COUNT(*) as occurrence_count')
    ->fromSub(function ($query) use ($services_id) {
        $query->selectRaw('jsonb_each_text(user_info->\'languages\') AS (lang, proficiency)')
        ->from('users')
        ->whereIn('id', $services_id);
    }, 'user_languages')
    ->groupBy('lang')
    ->orderBy('occurrence_count', 'desc')
    ->get();

方法二说明

这种方式直接在数据库中完成JSON解析、拆分和统计,避免了把大量数据加载到内存中,适合数据量较大的场景。但需要确保你的数据库版本支持对应的JSON函数。

内容的提问来源于stack exchange,提问作者Ghiath Al-Khatib

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:32:43