elasticsearch 及laravel中的使用

elasticsearch-laravel

1. 概念

1. 什么是ES

Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene 基础之上。然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:

  • 一个分布式的实时文档存储,每个字段 可以被索引与搜索
  • 一个分布式实时分析搜索引擎
  • 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据

2. 基本概念

1. 索引(Index)

​ Elastic 会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。索引是很多文档的集合,这些文档都具备一些相似的特征。例如,你可以分别创建客户,产品目录和其他数据的索引。索引是通过名字(必须是小写的)区分的,当执行索引,搜索,更新和删除操作时,这个名字将会被用来引用实际的索引。

2. 类型(Type)

​ 你可以在索引中定义一个或多个类型。类型是索引的一个逻辑分类或划分,它的概念完全取决于你自己如何去理解。通常,类型是为一些具备公共字段的文档定义的。例如,假想你在运行一个博客平台,并且把其全部的数据都存储索引中。你可以在索引中定义一个用于保存用户数据的类型,另一个用于保存博客数据的类型,还有一个用于保存评论数据的类型。在 7.x 以上的版本逐渐去掉类型

3. 文档(Document)

​ 文档是可以被索引的基本单位。例如,你可以用一个文档保存单个客户的数据,另一个文档保存单个产品的数据,还有一个文档保存单个订单的数据。文档使用一种互联网广泛存在的数据交换格式保存-JSON。

你可以在索引/类型中存储大量你想存储的数据。值得注意的是,尽管文档本质上是存放在索引中,但实际上是被索引到索引中的一个类型中。

4. 节点(Node)

​ 节点是一个服务器,也是集群的一部分,它存储你的数据,并参与集群的索引和搜索。和集群一样,节点也是通过唯一的名字去区分,默认名字是一个随机的UUID,当服务器启动的时候就会设置到节点。你也可以自定义节点的名称。名称对管理员来说十分重要,它可以帮助你辨认出集群中的各个服务器和哪个节点相对应。

5. 集群(Cluster)

​ 集群是一个或多个节点(服务器)的集合,它们联合起来保存所有的数据(索引以分片为单位分散到多个节点上保存)并且可以在所有的节点上进行索引和搜索操作。集群通过一个唯一的名字区分,默认的名字是“elasticsearch”。这个名字十分重要,因为一个节点仅仅可以属于一个集群,并根据集群名称加入集群。

2. 安装

1. windows 安装启动

  • java环境安装

​ 由于elasticsearch是基于java运行的,在安装elasticsearch之前必须安装java运行环境

​ 从Oracle 官网下载并安装对应的java环境

​ 将java添加到环境变量

  • elasticsearch 下载安装

​ 从官网下载elasticsearch最新的版本

​ 下载后解压缩,进入bin目录

​ 运行elasticsearch.bat文件即可启动elasticsearch服务

​ 默认启动端口为 9200 , 访问地址 127.0.0.1:9200 即可看见elasticsearch的启动信息

  • Kibana 下载安装

​ 从官网下载与elasticsearch 对应的Kibana版本(必须与elasticsearch版本一致方可启动)

​ 下载后解压缩,进入bin目录

​ 运行Kibana.bat文件启动Kibana服务

​ 默认启动端口为 5600 , 浏览器输入127.0.0.1:5600即可访问

  • IK 中文分词器安装

​ 从GitHub下载分词器对应版本(与elasticsearch版本保持一致)

​ 解压缩后移动到 elasticsearch 的 plugins 文件夹下并重命名为ik

​ 重新启动elasticsearch服务即可使用 IK 中文分词器

2. Linux 安装启动

3. 分词

1. 自定义分词器

对于逗号分割的标签字段自定义通过逗号分词的分词器

PUT /zsj/?pretty
{
"settings": {
  "index": {
    "number_of_shards": "1",
    "number_of_replicas": "1"
  },
  "analysis": {
        "analyzer": {
            "comma": {
                 "type": "pattern",
                 "pattern":","
                }
            }
        }
    }
}

4. laravel开发过程

1. 下载安装扩展驱动

安装laravel/scout

安装ElasticSearch laravel 驱动

配置ES驱动

1. 安装 laravel/scout

参考laravel文档

2. 安装 ElasticSearch 驱动

参考GitHub

3. 配置 ES 驱动

'driver' => env('SCOUT_DRIVER', 'elasticsearch'),
  //增加一个驱动
 'elasticsearch' => [
         'index' => env('ELASTICSEARCH_INDEX', 'laravel56_shop'),
         'hosts' => [
             env('ELASTICSEARCH_HOST', 'http://127.0.0.1:9200'),
         ],
  ],

2. 创建模板和索引

创建索引和模板的配置文件

使用laravel命令行生成模板和索引

1. 创建Command命令

php artisan make:command ESInit会生成一个 Console/Commands 文件夹和 ESInit.php 的文件

2. 编辑文件handle函数
<?php

namespace App\Console\Commands;

use GuzzleHttp\Client;
use Illuminate\Console\Command;

class ESinit extends Command
{
    /**
     * 控制台命令的名称和签名。
     *
     * @var string
     */
    protected $signature = 'es:init';

    /**
     * 控制台命令的描述
     *
     * @var string
     */
    protected $description = 'init laravel elasticsearch for shopTitle';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     * 向ES中发送reset风格的请求
     * @return mixed
     */
    public function handle()
    {
        //创建template
        $client = new Client();
        $url = config('scout.elasticsearch.hosts')[0] . '/_template/tmp';
        $params = [
            'json' => [
                'template' => config('scout.elasticsearch.index'),
                'mappings' => [
                    '_default_' => [
                        'dynamic_templates' => [
                            [
                                'strings' => [
                                    'match_mapping_type' => 'string',
                                    'mapping' => [
                                        'type' => 'text',
                                        'analyzer' => 'ik_smart',
                                        'fields' => [
                                            'keyword' => [
                                                'type' => 'keyword'
                                            ],
                                        ],
                                    ],
                                ],
                            ]
                        ],
                    ],
                ],
            ],
        ];
        //想URL发送参数创建template
        $client->put($url, $params);
        //做记录 显示在命令行
        $this->info('============ 创建模板成功 ==============');

        //创建index
        $url = config('scout.elasticsearch.hosts')[0] . '/' . config('scout.elasticsearch.index');
        $params = [
            'json' => [
                'settings' => [
                    'refresh_interval' => '5s',
                    'number_of_shards' => 1,
                    'number_of_replicas' => 0,
                ],
                'mappings' => [
                    '_default_' => [
                        '_all' => [
                            'enabled' => false
                        ],
                    ],
                ],
            ],
        ];
        $client->put($url, $params);
        $this->info('============ 创建索引成功 ==============');
    }
}
3. 挂载命令

编辑 App\Console\Kernel.php 文件

/**
     * 将ESInit类加入到 protected $commands数据中
     *
     * @var array
     */
    protected $commands = [
        ESinit::class
    ];

使用 php artisan 查看命令是否已生成

使用 php artisan es:init 命令为 ES 生成模板和索引

3. 数据写入和同步更新

1. 创建要同步的数据的表模型

创建 product 表模型

<?php

namespace App\Models\Admin;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

/**
 * Class Product
 * @package App\Models\Admin
 */
class Product extends Model
{
    use Searchable;
 
    /**
     * 定义索引里的type值,重写
     * @return string
     */
    public function searcheableAs()
    {
        return "product";
    }

    /**
     * 定义那些字段需要搜索
     * @return array
     */
    public function searchableArray()
    {
        return [
            'title' => $this->title,
            'descr' => $this->descr
        ];
    }
}

2. 使用scout导入数据

php artisan scout:import "App\Models\Product"

5. 查询方法

1. 一般查询

查询所有数据

GET /zsj/_search
{
  "size": 2000
}

通过字段匹配查询

GET /zsj/_search
{
  "query": {
    "match": {
      "author": "joker · 小丑"
    }
  }
}

多字段联合查询和过滤

GET /zsj/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "subject": {
              "query": "林_Linplustar",
              "boost": 1.2
            }
          }
        },
        {
          "match": {
            "tags": {
              "query": "林_Linplustar",
              "boost": 2.0
            }
          }
        },
        {
          "match_phrase": {
            "author": {
              "query": "林_Linplustar",
              "boost": 40.0
            }
          }
        },
        {
          "match_phrase": {
            "big_class": {
              "query": "林_Linplustar",
              "boost": 6.0
            }
          }
        },
        {
          "match_phrase": {
            "small_class": {
              "query": "林_Linplustar",
              "boost": 3.0
            }
          }
        }
      ],
      "must": [
        {
          "range": {
            "displayorder": {
              "gte": 0
            }
          }
        },
        {
          "range": {
            "dateline": {
              "gte": 1497954476
            }
          }
        },
        {
          "range": {
            "digest": {
              "gte": 0
            }
          }
        }
      ]
    }
  },
  "size": 500
}

2. 其他查询

查询某个字段的分词情况

GET zsj/thread/{id}/_termvectors?fields={field}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271