php - 根据 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 的应用答案
解决方案
由于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;