voidgraphics / laravel-searchable
Eloquent模型搜索特性。
1.14
2020-10-18 13:59 UTC
Requires
- php: >=5.4.0
- ext-mbstring: *
- illuminate/database: ^4.2 | ^5.0 | ^6.0 | ^7.0 | ^8.0
- dev-master
- 1.14
- 1.13
- 1.12.0
- 1.11.0
- 1.10.4
- 1.10.3
- 1.10.2
- 1.10.1
- 1.10.0
- 1.9.6
- 1.9.5
- 1.9.4
- 1.9.3
- 1.9.2
- 1.9.1
- 1.9.0
- 1.8.0
- 1.7.3
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.15
- 1.5.14
- 1.5.13
- 1.5.12
- 1.5.11
- 1.5.10
- 1.5.9
- 1.5.8
- 1.5.7
- 1.5.6
- 1.5.5
- 1.5.4
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.5
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4
- 1.3
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.0
- 0.1.2
This package is not auto-updated.
Last update: 2024-09-30 08:07:30 UTC
README
Searchable是一个为Laravel 7设计的特性,它为Eloquent模型添加了简单的搜索功能。
Searchable允许你在表中执行搜索,并为表及其关系中的每个字段设置优先级。
这不是为大规模搜索优化的,但有时你只需要让它简单(尽管它并不慢)。
安装
只需将包添加到你的composer.json
文件中,并运行composer update
。
"voidgraphics/laravel-searchable": "1.*"
使用方法
将特性添加到你的模型和搜索规则中。
use Voidgraphics\Searchable\SearchableTrait; class User extends \Eloquent { use SearchableTrait; /** * Searchable rules. * * @var array */ protected $searchable = [ /** * Columns and their priority in search results. * Columns with higher values are more important. * Columns with equal values have equal importance. * * @var array */ 'columns' => [ 'users.first_name' => 10, 'users.last_name' => 10, 'users.bio' => 2, 'users.email' => 5, 'posts.title' => 2, 'posts.body' => 1, ], 'joins' => [ 'posts' => ['users.id','posts.user_id'], ], ]; public function posts() { return $this->hasMany('Post'); } }
现在你可以搜索你的模型了。
// Simple search $users = User::search($query)->get(); // Search and get relations // It will not get the relations if you don't do this $users = User::search($query) ->with('posts') ->get();
搜索分页
就像laravel默认查询一样简单
// Search with relations and paginate $users = User::search($query) ->with('posts') ->paginate(20);
混合查询
搜索方法与任何Eloquent方法兼容。你可以做这样的事情
// Search only active users $users = User::where('status', 'active') ->search($query) ->paginate(20);
自定义阈值
默认的可接受相关性的阈值是所有属性相关性的总和除以4。要更改此值,可以将第二个参数传递给search(),如下所示
// Search with lower relevance threshold $users = User::where('status', 'active') ->search($query, 0) ->paginate(20);
上面的代码将按相关性顺序返回所有用户。
全文搜索
默认情况下,多词搜索词会被分割,Searchable会逐个搜索每个单词。相关性在优先级排序匹配多个单词的匹配项时发挥作用。如果你想优先考虑包含多词搜索(因此,不分割成单词)的匹配项,可以通过将第三个值设置为true来启用全文搜索。示例
// Prioritize matches containing "John Doe" above matches containing only "John" or "Doe". $users = User::search("John Doe", null, true)->get();
如果你明确只想搜索全文匹配,可以通过将第四个参数设置为true来禁用多词分割。
// Do not include matches that only matched "John" OR "Doe". $users = User::search("John Doe", null, true, true)->get();
它是如何工作的?
Searchable构建一个查询,通过Laravel的Eloquent搜索你的模型。以下是一个示例查询
Eloquent模型
use Voidgraphics\Searchable\SearchableTrait; class User extends \Eloquent { use SearchableTrait; /** * Searchable rules. * * @var array */ protected $searchable = [ 'columns' => [ 'first_name' => 10, 'last_name' => 10, 'bio' => 2, 'email' => 5, ], ]; }
搜索
$search = User::search('Sed neque labore', null, true)->get();
结果
select `users`.*, -- If third parameter is set as true, it will check if the column starts with the search -- if then it adds relevance * 30 -- this ensures that relevant results will be at top (case when first_name LIKE 'Sed neque labore%' then 300 else 0 end) + -- For each column you specify makes 3 "ifs" containing -- each word of the search input and adds relevace to -- the row -- The first checks if the column is equal to the word, -- if then it adds relevance * 15 (case when first_name LIKE 'Sed' || first_name LIKE 'neque' || first_name LIKE 'labore' then 150 else 0 end) + -- The second checks if the column starts with the word, -- if then it adds relevance * 5 (case when first_name LIKE 'Sed%' || first_name LIKE 'neque%' || first_name LIKE 'labore%' then 50 else 0 end) + -- The third checks if the column contains the word, -- if then it adds relevance * 1 (case when first_name LIKE '%Sed%' || first_name LIKE '%neque%' || first_name LIKE '%labore%' then 10 else 0 end) + -- Repeats with each column (case when last_name LIKE 'Sed' || last_name LIKE 'neque' || last_name LIKE 'labore' then 150 else 0 end) + (case when last_name LIKE 'Sed%' || last_name LIKE 'neque%' || last_name LIKE 'labore%' then 50 else 0 end) + (case when last_name LIKE '%Sed%' || last_name LIKE '%neque%' || last_name LIKE '%labore%' then 10 else 0 end) + (case when bio LIKE 'Sed' || bio LIKE 'neque' || bio LIKE 'labore' then 30 else 0 end) + (case when bio LIKE 'Sed%' || bio LIKE 'neque%' || bio LIKE 'labore%' then 10 else 0 end) + (case when bio LIKE '%Sed%' || bio LIKE '%neque%' || bio LIKE '%labore%' then 2 else 0 end) + (case when email LIKE 'Sed' || email LIKE 'neque' || email LIKE 'labore' then 75 else 0 end) + (case when email LIKE 'Sed%' || email LIKE 'neque%' || email LIKE 'labore%' then 25 else 0 end) + (case when email LIKE '%Sed%' || email LIKE '%neque%' || email LIKE '%labore%' then 5 else 0 end) as relevance from `users` group by `id` -- Selects only the rows that have more than -- the sum of all attributes relevances and divided by 4 -- Ej: (20 + 5 + 2) / 4 = 6.75 having relevance > 6.75 -- Orders the results by relevance order by `relevance` desc
贡献
欢迎任何人贡献。Fork,做出你的更改,然后提交一个pull request。