搜索引擎之laravel中使用elasticsearch(一)
一、概述
Elasticsearch官方提供了Composer包可直接引用就好,不过要注意;如果你使用的elastcsearch不是最新的那么我建议你指定合适的版本下载,而不要采用最新的,因为不同版本的es提供的api不同
https://packagist.org/packages/elasticsearch/elasticsearch
除了es外在laravel中也可以使用Scout;不过es中的查找方式功能比scout全,相对来说es可以更好地满足电商系统的需求
composer 命令:
composer require elasticsearch/elasticsearch
配置:
然后修改.env
添加Elasticsearch到laravel的容器中
可以通过tinker 进行测试
app(‘es’)->info();
我们可以查询之前给es配置的索引test中的数据
app('es')->get(['index' => 'test', 'type' => '_doc', 'id' => 1]);
二、使用elasticsearch创建商品的索引搜索
因为在项目中是需要对于商品进行查询的,也就是输入商品相关名称的关键字然后查找对应的数据;
这里还是需要解释es的搜索,es搜索是根据与文档查找的而不是根据与数据库进行查询。
也就是说实际上我们需要先把数据放到es中,也就是存在文档中,然后通过es的对应索引进行查找最终显示
在这个时候那么我们就需要整理一下需要事先存在于es文档中的数据内容及数据的格式。
对于商品的信息来说我们目前最为主要的就是展示商品的goods信息,以及sku,分类信息,属性
设置虚拟字段attr_name
测试之后的结果
及如上就是实际会存在es中的数据内容及其格式
创建商品的索引
curl –XPUT http://localhost:9200/goods/
然后添加文档
curl -H'Content-Type: application/json' -XPUT http://localhost:9200/goods/_mapping/_doc?pretty -d'{
"properties": {
"title": { "type": "text", "analyzer": "ik_smart" },
"long_title": { "type": "text", "analyzer": "ik_smart" },
"category_id": { "type": "integer" },
"category_path" : { "type": "keyword" } ,
"category_name" : { "type": "keyword" } ,
"desc": { "type": "text", "analyzer": "ik_smart" },
"sale": { "type": "integer" },
"sort": { "type": "integer" },
"state": { "type": "integer" },
"pv": { "type": "integer" },
"skus": {
"type": "nested",
"properties": {
"attr_name": { "type": "text", "analyzer": "ik_smart" },
"price": { "type": "scaled_float", "scaling_factor": 100 },
"stock": { "type": "integer" }
}
}
}
}'
"analyzer": "ik_smart" 代表这个字段需要使用 IK 中文分词器分词
还有有一些字段的类型是 keyword,这是字符串类型的一种,这种类型是告诉 Elasticsearch 不需要对这个字段做分词,通常用于邮箱、标签、属性等字段。
skus的字段类型是 nested,代表这个字段是一个复杂对象,由下一级的 properties 字段定义这个对象的字段。我们的『商品 SKU』明明是对象数组,为什么这里可以定义成对象?这是 Elasticsearch 的另外一个特性,每个字段都可以保存多个值,这也是 Elasticsearch 的类型没有数组的原因,因为不需要,每个字段都可以是数组
然后测试
注意需要重新打开tinker
$goods = App\Models\Goods::find(78)->toESArray();
app('es')->index(['id' => $goods['id'], 'index' => 'goods', 'type' => '_doc', 'body' => $goods]);
app('es')->get(['index' => 'goods', 'type' => '_doc', 'id' => 78]);