如何使用多个关键字Laravel 5从数据库中获取和排序最相关的条目

时间:2017-03-07 20:04:15

标签: php mysql sql laravel laravel-5

我无法处理多个关键字并根据相关性查询数据库。我想搜索每一行,如果根据我选择的列每行匹配的关键字超过1个,则首先对这些条目进行排序。

我确实有一些工作,但它只是提取列中没有特定顺序或相关性的关键字的所有条目。

以这个工作为例:

$search_terms = array('York', 'North Yorkshire');

$properties = Property::where(function ($q) use ($search_terms) {
            foreach ($search_terms as $value) {
                $q->orWhere('address1', 'like', "%{$value}%");
                $q->orWhere('address2', 'like', "%{$value}%");
                $q->orWhere('postcode', 'like', "%{$value}%");
                $q->orWhere('city_town', 'like', "%{$value}%");
                $q->orWhere('county', 'like', "%{$value}%");
            }
        })->paginate(25);

这样可以使用我选择的任何列中的关键字撤回所有条目。在本例中,来自city_town列的约克和来自county列的北约克郡

我需要查询来检查这些关键字的每一行,并带回这些关键字中存在 ALL 的条目,然后是之后存在的一个或多个(我的示例现在执行此操作) )。

非常感谢能够提供帮助的任何人。

2 个答案:

答案 0 :(得分:4)

好吧,也许一些SQL魔术师可以为您提供更好的SQL解决方案。但在那之前......

这就是我用Laravel collections(用php排序)的方法:

$search_terms = array('York', 'North Yorkshire');

$properties = Property::where(function ($q) use ($search_terms) {
            foreach ($search_terms as $value) {
                $q->orWhere('address1', 'like', "%{$value}%");
                $q->orWhere('address2', 'like', "%{$value}%");
                $q->orWhere('postcode', 'like', "%{$value}%");
                $q->orWhere('city_town', 'like', "%{$value}%");
                $q->orWhere('county', 'like', "%{$value}%");
            }
        })->paginate(25);

$props = ['address1', 'address2', 'postcode', 'city_town', 'county'];

$properties = $properties->sortByDesc(function($i, $k) use ($search_terms, $props) {
    // The bigger the weight, the higher the record
    $weight = 0;
    // Iterate through search terms
    foreach($search_terms as $searchTerm) {
        // Iterate through properties (address1, address2...)
        foreach($props as $prop) { 
            // Use strpos instead of %value% (cause php)
            if(strpos($i->{$prop}, $searchTerm) !== false)
                $weight += 1; // Increase weight if the search term is found
        }
    }

    return $weight;
});

$properties = $properties->values()->all();

答案 1 :(得分:0)

我绝对希望您能在1年内解决您的问题,但是我想我也遇到了同样的问题,这就是我的处理方式。 (我认为devk解决方案在性能方面有点贪婪)。我正在使用Laravel 5.6 btw

我在数据库中获得了一些字符串格式的专业知识,下面是一个示例,表明专业知识可能具有的价值:

user->expertises = "SAP, ERP, team management"

我想在搜索领域投入一些专业知识,并获得最相关的结果:

$input = "SAP, nagement" // Expertises searched, volontary 'nagement' uncompleted word
$keywords = explode(", ", $input); // Array of keyword

$raw = "(";
foreach($keywords as $key) {
    $raw .= "(user.expertises LIKE '%".$key."%')+";
}
$raw = substr($raw, 0, -1); // Remove the last "+"
$raw .= ") as weight";
// End result :
// ((user.expertises LIKE '%SAP%')+(user.expertises LIKE '%nagement%')) 
// as weight

// It will do smtg like '(0+1+1) as weight' for example, for each user


$request = User::select('*')->addSelect(DB::raw($raw));
return $request->orderBy('weight', 'DESC')->paginate(10);

我的示例用户的体重为2。并且将位于结果的顶部(因为权重在0到2之间,具体取决于关键字的数量)