elasticsearch-MySQL

1.系统原理

要通过elasticsearch实现数据检索,首先要将数据导入elasticsearch,并实现数据源与elasticsearch数据同步.这里使用的数据源是Mysql数据库.目前mysql与elasticsearch常用的同步机制大多是基于插件实现的,常用的插件包括:logstash-input-jdbc,go-mysql-elasticsearch, elasticsearch-jdbc。

系统原理: Elasticsearch:一个基于Lucene的搜索引擎。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,具有近实时、可靠、开箱即用等特点。

通过获取MySQL的binlog日志,通过解析binlog,将解析后的数据推入消息队列中),在业务中建立kafka消费端,将数据存入ES。

2.背景

目前电商平台的商品搜索,采用的是将用户输入的词汇传入后台,通过对数据库中商品名title进行模糊匹配,进行商品搜索。这种方式,无法使用索引。效率比较低。并且只是对商品名称的单字段搜索,局限性也比较大。基于这些情况,希望引入搜索引擎来改善搜索效率问题。

2.1要解决的问题

1.尽量保持原有的实时性,特别对于商品的价格数据等

2.提高搜索效率,降低数据库压力

3.支持原有的“热度”,“价格”, “新品” 三种排序方式

4.便捷的维护方式

5.平滑升级

2.2技术选型

1.近实时的更新(1s延时)

2.结构化数据良好的搜索支持

3.在全文搜索中提供了丰富的搜索方式和大数据分析,也可以作为以后其他搜索需求的搜索引擎。

4.RESTFUL风格接口支持所有功能

5.对php和java都有良好的支持

6.已有现成的中文分词器ik对搜索的中文内容进行分词处理。

2.3电商商品搜索方案规划

1.索引数据的更新方式

 

操作步骤:

1.保持原有的在后台商品管理功能对商品数据进行的操作

2.商品数据修改完成后,调用统一的商品更新接口,对商品数据进行更新操作。受商品活动、销量的影响,保存的数据本次不保证价格和销量数据的有效性。

3.商品信息同步API提供两种数据更新方式:

a.全量更新(不传商品id时,提供对数据的全量复写功能)

b.单id操作(传递商品id,以商品id作为es文档的id值)

2.商品搜索

 

操作步骤:

1.前台输入搜索关键词和选择排序方式

2.对es中title,seo关键词等字段进行索引筛选,获取符合条件的商品id

3.通过商品id查询ecstore中的实时性数据,比如实时活动价格,商品销量

4.对搜索引擎获取的数据和ecstore中的数据进行整合,合并成需要返回的数据进行返回。

3使用php来做电商实例拓展

3.1安装 PHP 扩展

我这里使用的是 composer 安装 elasticsearch-php。在 composer.json 文件中加入 "elasticsearch/elasticsearch": "~6.0",执行 composer update

{
  "require": {
    // ...
    "elasticsearch/elasticsearch": "~6.0"
    // ...
  }
}

3.2使用PHP进行数据实操

3.2.1创建表和测试数据,我这里准备了一张商品表来进行测试。

create table products(
  id int not null primary key auto_increment,
  title varchar(200) not null comment '商品标题',
  content text comment '商品详情'
);
​
insert into products(title, content) values ('商品标题1', '商品详情1'),
('商品标题2', '商品详情2'),
('商品标题3', '商品详情3');

从 Mysql 读取数据

try {
  $db = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
​
  $sql = 'select * from products';
​
  $query = $db->prepare($sql);
  $query->execute();
  $lists = $query->fetchAll();
  print_r($lists);
} catch (Exception $e) {
  echo $e->getMessage();
}

3.2.2实例化elasticsearch

require './vendor/autoload.php';
use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()->build();

名词解释:索引相当于 MySQL 中的表,文档相当于 MySQL 中的行记录。

elasticsearch 的动态性质,在添加第一个文档的时候自动创建了索引和一些默认设置。

3.2.3将文档加入索引

如何将数据通过客户端,添加数据至elasticsearch 如下:

foreach ($lists as $row) {
  $params = [
    'body' => [
      'id' => $row['id'],
      'title' => $row['title'],
      'content' => $row['content']
    ],
    'id' => 'product_' . $row['id'],
    'index' => 'products_index',
    'type' => 'products_type'
  ];
  $client->index($params);
}

3.2.4从索引中获取文档

$params = [
  'index' => 'products_index',
  'type' => 'products_type',
  'id' => 'products_1'
];
$res = $client->get($params);
print_r($res);

3.2.5从索引中删除文档

$params = [
  'index' => 'products_index',
  'type' => 'products_type',
  'id' => 'products_1'
];
$res = $client->delete($params);
print_r($res);

3.2.6删除索引

$params = [
    'index' => 'products_index'
];
$res = $client->indices()->delete($params);
print_r($res);

3.2.7创建索引

$params['index'] = 'products_index';  
$params['body']['settings']['number_of_shards'] = 2;  
$params['body']['settings']['number_of_replicas'] = 0;  
$client->indices()->create($params);

3.2.8搜索

$params = [ 
  'index' => 'products_index',
  'type' => 'products_type',
];      
​
$params['body']['query']['match']['content'] = 'Laravel';
$res = $client->search($params);
print_r($res);

4.常见问题

5.1创建索引的时候报错

如下:

Root mapping definition has unsupported parameters: [test_parent : {_source={enabled=true}}]"}},“status”:400}

原因:elasticsearch7默认不在支持指定索引类型,默认索引类型是_doc,如果想改变,则配置include_type_name: true 即可(这个没有测试,官方文档说的,无论是否可行,建议不要这么做,因为elasticsearch8后就不在提供该字段)。

5.2用php查询所有文档时需要转换数组为对象

es查询所有文档的json:

{
    "query": {
        "match_all": {}
    }
}

使用php查询所有文档的时候需要把数组转换成对象,因为match_all传空或者传json数组都会报错。

商品实例如何使用elasticsearch完成我们在

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐