Maison > Article > développement back-end > 使用 Laravel Search 扩展包基于 Elasticsearch、 Algolia 以及 ZendSearch 实现全文搜索功能
Laravel Search扩展包为不同的全文搜索服务提供了统一的API,当前支持的搜索服务包括 ElasticSearch 、 Algolia 和 ZendSearch 。
我们通过Composer来安装这个依赖包:
composer require mmanos/laravel-search dev-master
安装完成后,在 config/app.php 中注册服务提供者到 providers 数组:
'providers' => array( // ... Mmanos\Search\SearchServiceProvider::class,)
然后添加门面到 aliases 数组:
'aliases' => array( // ... 'Search' => Mmanos\Search\Facade::class,)
发布扩展包自带的配置文件到应用配置目录下:
php artisan vendor:publish
以下是相关搜索驱动需要的依赖包:
该扩展包提供了简洁的语法来处理默认索引:编辑配置文件中的 default_index 来修改这个值。
使用这个扩展包处理索引非常简单,只需要为文档提供一个唯一的标识符并指定一个关联数组到该索引即可。
如果你首次访问这个索引不存在,则该索引会自动创建。
添加一个id为1的默认索引到文档:
Search::insert(1, array( 'title' => 'My title', 'content' => 'The quick brown fox...', 'status' => 'published',));
注:id可能是一个字符串或整型数据,这个id可用于删除记录也可以在搜索结果中返回。
你可以在文档中存储额外的参数以便在后续搜索结果中获取到,这个特性在引用时间戳或其他标识记录时很有用。
Search::insert( "post-1", array( 'title' => 'My title', 'content' => 'The quick brown fox...', 'status' => 'published', ), array( 'created_at' => time(), 'creator_id' => 5, ));
注:额外参数并没有被索引但是存储在索引中以便后续获取到。
可以从索引中通过id删除一个文档:
Search::delete(1);
Search::deleteIndex();
搜索默认索引对应文档中content包含“fox”的所有记录:
$results = Search::search('content', 'fox')->get();
$results = Search::search(array('title', 'content'), 'fox')->get();
$results = Search::search(null, 'fox')->get();
$results = Search::search('content', 'update', array('fuzzy'=>true))->get();
注:你也可以传递一个介于0和1之间的数值给fuzzy参数,这个数值越接近1表示越相似,默认是0.5
你也可以在查询中使用过滤器,过滤器尝试匹配你指定的整个语句:
$results = Search::search('content', 'fox') ->where('status', 'published') ->get();
注:如果指定值包含多个单词的话过滤器并不能保证精准匹配整个字段值。
有些驱动支持基于位置的搜索:
$results = Search::search('content', 'fox') ->whereLocation(36.16781, -96.023561, 10000) ->get();
上述参数分别表示纬度、经度和距离(米)。
注:目前只有 algolia 驱动支持基于位置的搜索,此外需要确保每个索引记录包含本地信息,如:_ geoloc => ['lat' => 1.23, 'lng' => 1.23] 。
$results = Search::search('content', 'fox') ->where('status', 'published') ->limit(10) // Limit 10 ->get();$results = Search::search('content', 'fox') ->where('status', 'published') ->limit(10, 30) // Limit 10, offset 30 ->get();
$paginator = Search::search('content', 'fox')->paginate(15);
$results = Search::select('id', 'created_at') ->search('content', 'fox') ->get();
$results = Search::select('id', 'created_at') ->where('title', 'My title') ->where('status', 'published') ->search('content', 'fox') ->search('content', 'quick') ->limit(10) ->get();
Search::search('content', 'fox')->delete();
如果你需要处理多个索引可以在指定索引名后像单个索引一样使用上述方法。添加文档到名为“posts”的索引:
Search::index('posts')->insert(1, array( 'title' => 'My title', 'content' => 'The quick brown fox...', 'status' => 'published',));
查询 content 包含 fox 且 status 为 published 的posts:
$results = Search::index('posts')->search('content', 'fox') ->where('status', 'published') ->get();
从posts中删除id为1的文档:
Search::index('posts')->delete(1);
删除所有posts:
Search::index('posts')->deleteIndex();
如果你想要对查询有更多控制,可以在所有条件添加到查询后在查询执行之前添加一个回调函数:
$results = Search::index('posts')->select('id', 'created_at') ->search('content', 'fox') ->addCallback(function ($query) { // Make changes to $query... return $query; }) ->get();
由于每个驱动都有其自己的 $query 对象/数组,你可以只为某一个驱动执行回调:
$results = Search::index('posts')->select('id', 'created_at') ->search('content', 'fox') ->addCallback(function ($query) { // Adjust pagination for an elasticsearch query array. $query['from'] = 0; $query['size'] = 20; return $query; }, 'elasticsearch') ->get();
注:你也可以传递一个驱动数组作为第二个参数。