laravel Scout包在elasticsearch中的应用
laravel Scout包在elasticsearch中的应用
laravel的Scout包是针对自身的Eloquent模型开发的基于驱动的全文检索引擎。意思就是我们可以像使用ORM一样使用检索功能。不管你用的是什么搜索引擎,scout包给你封装好了几个方法
use Laravel\Scout\Builder;
abstract public function update($models);
abstract public function delete($models);
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, $perPage, $page);
abstract public function map($results, $model);
你只需要创建一个引擎(比如es引擎)就可以使用orm来操作search了。
可惜laravel的scout包只提供了Algolia的驱动。我个人很喜欢的es并没有提供驱动。好在网上有人分享了驱动,比如 https://github.com/ErickTamayo/laravel-scout-elastic
看里面的代码,其实很简单,两个类,一个类ElasticsearchEngine用于实现Scout定义的几个方法,一个类ElasticsearchProvider用于做服务注册。我们使用composer require就能用好这个类了。这里就不说了。
scout包在es中的存储
说说laravel的scout包在es里面是怎么存储的。首先,在配置文件里面elasticsearch创建一个index
'driver' => env('SCOUT_DRIVER', 'elasticsearch'),
...
'elasticsearch' => [
'index' => env('ELASTICSEARCH_INDEX', 'laravel'),
'hosts' => [
env('ELASTICSEARCH_HOST', 'http://localhost'),
],
],
...
然后每个对应的model都是不同的type。这个type的名字是在model里面定义的。
class Post extends Model
use Laravel\Scout\Searchable;
class Post extends Model
{
use Searchable;
protected $table = "posts";
/*
* 搜索的type
*/
public function searchableAs()
{
return 'posts_index';
}
public function toSearchableArray()
{
return [
'title' => $this->title,
'content' => $this->content,
];
}
所以它里面每个条目实际上是这么一个结构:
我自己用的几点体验:
1 scout会很聪明把表的主键作为es的_id
这个真是非常赞,不需要存储一个id,做_id和id的关联了
2 scout在model做增删改查的时候会自动更新索引
这个也是我们最需要的,索引数据和数据库数据的同步使用代码进行保证了。当然,用代码保证可能并不是什么很好的方法,但是对于小型的网站来说,这个无疑增加了便捷性。
3 scout的建立索引方法是一个网站统一一个index, 不同的model使用不同的type
这种一个index多type的形式是否适用你的项目呢?不一定,如果你的model各不相同,可能多个index更好点。关于index和type的选择,https://www.elastic.co/blog/index-vs-type 可以参考这篇。所以这种方式可能更适合的是存储到es的都是文本的搜索。
4 search函数里面不能指定搜索字段
比如我的Post索引存入了title和content。那么我使用Post::search("china")的时候,搜索出来的结果就是title和content中包含有china的。如果我想搜索content中包含有"china"的,没办法,scout做不到,只能自己做扩展了。
5 分页指定了查询的字段名必须是query
这个意思是在搜索接口,你上交上来的查询接口必须是query=xx,形如http://127.0.0.1:8000/posts/search?query=china
看了源码发现这个query字段是由Scout/Builder写死在代码里面的...这个估计很多人用到这个分页的时候会踩进去
6 搜索的query强制使用通配符
这个是laravel-scout-elasticsearch的问题了,它在query的时候强制在搜索的前后使用上了通配符*,这个在标准分词器中文搜索的时候会出现问题,会变成一个词,具体问题可以看这个帖子:http://elasticsearch.cn/question/228
所以如果要使用标准分词器,需要把query的前后两个*都去掉,具体代码在vendor/tamayo/laravel-scout-elastic/src/ElasticsearchEngine.php中。
总结
scout还是主要偏向于统一搜索接口,如果你的网站很小,并且搜索只是作为文本搜索的话,那么用这个是非常合适的,但是如果你的搜索功能占你的网站大部分功能的话,那么我建议我们可以使用scout做搜索和数据库的同步,其他的搜索请求,我们使用elasticsearch/elasticsearch自己写比较好。
laravel Scout包在elasticsearch中的应用的更多相关文章
- laravel的scout包安装及laravel-es包安装
安装laravel/scout 作用:搜索驱动,可随时更换驱动,上层业务逻辑可不用改变 官网文档:https://laravel-china.org/docs/laravel/5.4/scout/12 ...
- [ Laravel 5.5 文档 ] 官方扩展包 —— 全文搜索解决方案:Laravel Scout
简介 Laravel Scout 为 Eloquent 模型全文搜索实现提供了简单的.基于驱动的解决方案.通过使用模型观察者,Scout 会自动同步更新模型记录的索引. 目前,Scout 通过 Alg ...
- 如何在Elasticsearch中安装中文分词器(IK+pinyin)
如果直接使用Elasticsearch的朋友在处理中文内容的搜索时,肯定会遇到很尴尬的问题--中文词语被分成了一个一个的汉字,当用Kibana作图的时候,按照term来分组,结果一个汉字被分成了一组. ...
- 【转】下载量最高的 100 个 Laravel 扩展包推荐
说明 Laravel 另一个令人喜欢的地方,是拥有活跃的开发者社区,而活跃的开发者社区带来的,是繁华的扩展包生态. 本文对 Packagist 上打了 Laravel 标签 的扩展包进行整理,截止到现 ...
- 探究ElasticSearch中的线程池实现
探究ElasticSearch中的线程池实现 ElasticSearch里面各种操作都是基于线程池+回调实现的,所以这篇文章记录一下java.util.concurrent涉及线程池实现和Elasti ...
- 使用 Composer 安装Laravel扩展包的几种方法
使用 Composer 安装Laravel扩展包的几种方法 以下的三种方法都是需要你在项目的根目录运行 第一种:composer install 如有 composer.lock 文件,直接安装,否则 ...
- 使用Hive读取ElasticSearch中的数据
本文将介绍如何通过Hive来读取ElasticSearch中的数据,然后我们可以像操作其他正常Hive表一样,使用Hive来直接操作ElasticSearch中的数据,将极大的方便开发人员.本文使用的 ...
- 第三百六十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)scrapy写入数据到elasticsearch中
第三百六十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)scrapy写入数据到elasticsearch中 前面我们讲到的elasticsearch( ...
- 四十六 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)scrapy写入数据到elasticsearch中
前面我们讲到的elasticsearch(搜索引擎)操作,如:增.删.改.查等操作都是用的elasticsearch的语言命令,就像sql命令一样,当然elasticsearch官方也提供了一个pyt ...
随机推荐
- unity脚本的运行顺序以及单例的实现
unity引擎把所有脚本先行编译后,在运行的时候一批,一批的函数进行执行. unity脚本自带函数执行顺序如下:将下面脚本挂在任意物体运行即可得到 Awake ->OnEable-> St ...
- 《剑指offer》— JavaScript(18)二叉树的镜像
二叉树的镜像 题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 相关知识 二叉树的镜像定义: 源二叉树 镜像二叉树 思路 有关二叉树的算法问题,一般都可以通过递归来解决.那么写一个正确的递归程序 ...
- Java Calendar.set 方法设置时间的问题
因项目需要,需要遍历一年中的其中几个月,获得每个月的用户数量. 变量有:开始时间--startDate,结束时间--endDate. 逻辑很简单:获取到开始时间的月份和结束时间的月份,然后得到月份差 ...
- Material Design学习-----TextInputLayout
TextInputLayout是为EditText提供了一种新的实现和交互方式.在传统的EditText中存在一个hint属性,是说在editext中没有内容时,默认的提示信息.当想edittext中 ...
- lxc.conf解析&lxc容器能力
lxd启动容器实际是生成lxc.conf.剩下的就是LXC对容器进行控制了.所以可认为lxc.conf就是lxd和lxc之间主要的接口.lxc.conf详细属性参考: http://manpages. ...
- nodejs中的异步流程序控制nsync
异步编程是指由于异步I/O等因素,无法同步获得执行结果时, 在回调函数中进行下一步操作的代码编写风格,常见的如setTimeout函数.ajax请求等等 http://cnodejs.org/topi ...
- [LeetCode] Is Subsequence 题解
前言 这道题的实现方法有很多,包括dp,贪心算法,二分搜索,普通实现等等. 题目 Given a string s and a string t, check if s is subsequence ...
- 问题 : lang.NoClassDefFoundError: org/springframework/core/annotation/AnnotatedElementUtils,的解决方法
今天在做junit 测试的时候 出现了一个问题,花了一段时间 才解决. java.lang.NoClassDefFoundError: org/springframework/core/annota ...
- Java的容器类小结
Java的容器类其实就是集合类,只是为了不与Collection接口混淆,国内基本翻译为容器类. 容器类分为两种:独立元素序列的Collection和键值对的Map. Collection主要有如下几 ...
- Servlet中编码在过滤器中的使用
1.先配置web.xml ->配置过滤器 // filter-class 为写的过滤器类 实现 Filter 接口 <filter> <filter-name>Encod ...