我无法处理多个关键字并根据相关性查询数据库。我想搜索每一行,如果根据我选择的列每行匹配的关键字超过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 的条目,然后是之后存在的一个或多个(我的示例现在执行此操作) )。
非常感谢能够提供帮助的任何人。
答案 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之间,具体取决于关键字的数量)