首页 > 解决方案 > 根据 LIKE 出现次数排序 Laravel Php

问题描述

目前我的网站上有一个简单的搜索引擎

我正在尝试匹配keyword所有领域。

这是简化的工作代码

$keyword_search = "Hello World";
$delimeter = ' '; //or your separator
$keywords = explode($delimeter, $keyword_search); 

$base_query = \App\Models\EntireSearchSite::where('id','!=',NULL);

foreach($keywords as $keyword){
    $base_query->where(function($query) use ($keyword){
            $query->where('part_number', 'like', '%' . $keyword . '%') 
                ->orWhere('part_name', 'like', '%' . $keyword . '%')
                ->orWhere('category', 'like', '%' . $keyword . '%')
                ->orWhere('description', 'like', '%' . $keyword . '%');
    });
    
}

$data = $base_query->paginate(20);
return $data;

我要做的是匹配所有关键字,计算所有匹配的关键字(每次出现)并Order By Desc从最高出现次数到最低次数。

如果我输入"Hello World"

它会找到所有匹配的数据"Hello World"

我有part_number, part_name, category, description字段

它将所有字段上的出现总数相加,并ORDER BY从高到低排列(DESC)

例子:

数据#1

匹配关键字的数量part_number为 0

匹配关键字的数量part_name为 2

匹配关键字的数量category为 0

匹配关键字的数量description为 0

总计 = 2

数据#2

匹配关键字的数量part_number为 0

匹配关键字的数量part_name为 0

匹配关键字的数量category为 2

匹配关键字的数量description为 10

总计 = 12

数据#3

匹配关键字的数量part_number为 0

匹配关键字的数量part_name为 0

匹配关键字的数量category为 0

匹配关键字的数量description为 5

总计 = 5

和 order by desc 应该是这样的

数据#2

数据#3

数据#1

更新*

尝试了@Anas的答案

$delimeter = ' '; //or your separator
$keywords = explode($delimeter, $keyword_search); 

$base_query = \App\Models\EntireSearchSite::where('id','!=',NULL);

foreach($keywords as $keyword){
    $base_query->where(function($query) use ($keyword){
            $query->where('part_number', 'like', '%' . $keyword . '%') 
                ->orWhere('part_name', 'like', '%' . $keyword . '%')
                ->orWhere('category', 'like', '%' . $keyword . '%')
                ->orWhere('description', 'like', '%' . $keyword . '%');
    });
}

foreach($keywords as $keyword){
            $base_query->selectRaw(function($querySelect) use ($keyword){
                $querySelect->selectRaw('
                    Round ((Char_length(Concat(
                        part_number, 
                        part_name,
                        category,
                        description

                    )) - Char_length(REPLACE ( Concat(
                        part_number, 
                        part_name,
                        category,
                        description
                    ), "'.$keyword.'", ""))) / Char_length("'.$keyword.'"))  AS count 
                ');

            });
}        

$data = $base_query->orderBy('count','DESC')->paginate(20);
return $data;

但我得到未定义的列数

更新

@Donkarnash 的应用答案

在此处输入图像描述

在此处输入图像描述

标签: phplaravel

解决方案


由于selectRaw在循环中使用,计数操作的别名不应该是count(重复循环的所有迭代)。而是应该'count'.$keyword使它成为一个唯一的别名。

同样,orderBy()也应该在循环中定义,以便按'count'.$keyword列排序。

$base_query = \App\Models\EntireSearchSite::where('id','!=',NULL);

foreach($keywords as $keyword){
    $base_query->where(function($query) use ($keyword){
        $query->where('part_number', 'like', '%' . $keyword . '%') 
            ->orWhere('part_name', 'like', '%' . $keyword . '%')
            ->orWhere('category', 'like', '%' . $keyword . '%')
            ->orWhere('description', 'like', '%' . $keyword . '%');
    });
}

foreach($keywords as $keyword) {
    $base_query->selectRaw('
        Round (
            (Char_length(Concat(email, name)) - Char_length(REPLACE ( Concat(email,name), "' . $keyword .'", ""))
        ) / Char_length("' . $keyword .'")
        ) AS count' .  $keyword
    )
    ->orderBy("count$keyword", "desc");
}

$data = $base_query->paginate(20);
return $data;

推荐阅读