php操作ElasticSearch
es-php客户端安装
php环境版本要求:
PHP >=7.1.0
ext-curl
ext-json
es-php扩展下载地址:
https://www.elastic.co/guide/en/elasticsearch/client/php-api/7.x/installation.html
引在thinkphp6框架中引入elasticsearch/elasticsearch包
composer require elasticsearch/elasticsearch="^7.0"
连接es-php客户端
参考文档:
https://www.elastic.co/guide/en/elasticsearch/client/php-api/7.x/connceting.html
# 引入开发包
use Elasticsearch\ClientBuilder;$client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build();
es-php索引创建删除
参考文档:
https://www.elastic.co/guide/en/elasticsearch/client/php-api/7.x/index_management.html
创建索引
$index = [
"index"=>"lampol",
"body"=>[
"mappings"=>[
"properties"=>[
"name"=>[
"type"=>"keyword"
],
"age"=>[
"type"=>"byte"
],
"addr"=>[
"type"=>"text",
"analyzer"=>"ik_max_word"
]
]
]
]
];
$response = $client->indices()->create($index);
判断索引是否存在、获取mapping数据结构、删除索引index
# 判断索引是否存在
$response = $client->indices()->exists(['index'=>'lampol']);# 获取mapping数据结构
$response = $client->indices()->getMapping(['index'=>'lampol']);# 删除索引index
$response = $client->indices()->delete(['index'=>'test1']);
es-php文档单个插入以及批量插入
文档单个插入
$doc = [
"index"=>'lampol',
"id"=>1,
"body"=>[
"name"=>"liudehua",
"age"=>33,
"addr"=>"中国广东省深圳市"
]
];
$response = $client->index($doc);
批量插入
$docs['body'] = [
['index'=>['_index'=>'lampol','_id'=>2]],
['name'=>'liming','age'=>43,'addr'=>'山东省青岛市'],
['index'=>['_index'=>'lampol','_id'=>3]],
['name'=>'郭富城','age'=>53,'addr'=>'山东省枣庄市']
];
$response = $client->bulk($docs);
es-php文档查询修改删除
# 文档查询id=3
$id = ['index'=>'lampol','id'=>3,'_source'=>['name','age'=>33]];
$response = $client->get($id);# 查询
$param = [
'index'=>'lampol',
'body'=>[
'query'=>[
'match'=>[
'addr'=>'深圳'
]
]
]
];
$response = $client->search($param);# 文档更新id=1
$doc = [
'index'=>'lampol',
'id'=>1,
'body'=>[
'doc'=>[
'age'=>53
]
]
];
$response = $client->update($doc);# 文档删除id=3
$id = ['index'=>'lampol','id'=>3];
$response = $client->delete($id);
ES实战logstash同步mysql数据到es
logstash安装及同步插件jdbc安装配置
1)安装logstash
下载路径(7.12.0版本)
https://www.elastic.co/cn/downloads/past-releases/logstash-7-12-0
# 将logstash解压到指定目录下
tar xzf logstash-7.12.0-linux-x86_64.tar.gz -C /usr/local/# 进入到
cd /usr/local/logstash-7.12.0# 创建java包目录
mkdir logstash-input-jdbc# 下载mysql-connector-java连接数据库java包放入到logstash-input-jdbc目录中
https://repo1.maven.org/maven2/mysql/mysql-connector-java/# 移动到指定目录
mv mysql-connector-java-8.0.12.jar /usr/local/logstash-7.12.0/logstash-input-jdbc/
2)配置数据库连接,同是指定读取的数据库表数据
vi /usr/local/logstash-7.12.0/logstash-input-jdbc/mysql.conf# 写入内容
# 数据输入
input{
jdbc {
# mysql的配置信息
jdbc_connection_string => "jdbc:mysql://192.168.1.106:3306/shop?characterEncoding=utf8&useSSL=false&serverTimezone=PRC&rewriteBatchedStatements=true"
jdbc_user => "root"
jdbc_password => "root"
# java驱动程序,logstash不自带的,如果我们不指定它,logstash则在其java类路径中查找(logstash/logstash-core/lib/jars)
jdbc_driver_library => "/usr/local/logstash-7.12.0/logstash-input-jdbc/mysql-connector-java-8.0.12.jar"
jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
# 定时调度器
schedule => "* * * * *"
# 指定追踪的递增字段名称
tracking_column => "id"
# 启用追踪,如果为true,则需要指定tracking_column。tracking_column值作为:sql_last_value,当设置为false时:sql_last_value为最后一次执行查询的时间
use_column_value => "true"
# 同步点文件,这个文件记录了上次的同步点,重启时会读取这个文件,这个文件可以手动修改
last_run_metadata_path => "usr/local/logstash-7.12.0/logstash-input-jdbc/tt.txt"
# 执行读取mysql数据库操作的sql语句,将数据查询出来,如果数据比较多加入limit限制
statement => "SELECT id,goods_title from goods"
# 默认时区
jdbc_default_timezone =>"Asia/Shanghai"
# 是否分页分批次从mysql中读取数据再写入es
# jdbc_paging_enabled => "true"
# jdbc_page_size => "1000" # 追踪字段的类型。目前只有"numeric"和"timestamp",默认numeric
# tracking_column_type => "timestamp"
}
}
# 过滤字段,一般不用过滤字段的
filter {
mutate {
remove_field => ["@timestamp","@version"]
}
}
# 数据输出
output{
elasticsearch {
hosts => ["http://192.168.1.128:9200"]
index => "goods"
document_id => "%{id}"
}
}
3)创建指定索引goods
PUT /goods
{
"mappings": {
"properties": {
"id":{
"type":"integer"
},
"goods_type":{
"type":"text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}
4)运行logstash服务
/usr/local/logstash-7.12.0/bin/logstash -f /usr/local/logstash-7.12.0/logstash-input-jdbc/mysql.conf
查看数据同步到es下goods情况
# 显示不同索引index下有多少数据
GET /_cat/indices?v
tp6实战ES搜索添加更新删除数据
tp6查询并列表高亮展示
搜索页面
D:\phpstudy_pro\WWW\thinkphp6\view\goods\search.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title>ElasticSearch PHP 实战搜索</title>
<link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap-theme.min.css">
</head><body class="bs-docs-home">
<div class="container theme-showcase">
<h1 style=" line-height:2em;"></h1><br/> <div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-12">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><strong>ElasticSearch PHP 实战搜索</strong></h3>
</div>
<div class="panel-body">
<div class="alert alert-dismissable">
<form action="/search" method="post" role="form" name="form1"> <div class="form-group">
<div class="input-group">
<input type="text" class="form-control" name="keywords" placeholder="关键词">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">开始搜索</button>
</span>
</div>
</div>
</form>
<button class="btn btn-success" onclick="location.href='/goods/create'" type="button">添加商品</button>
</div>
</div>
</div>
<div class="col-sm-3"></div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/js/bootstrap.min.js"></script>
</body>
</html>
列表页面:上一页、下一页、高亮展示列表数据
D:\phpstudy_pro\WWW\thinkphp6\view\goods\list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title>ElasticSearch PHP 实战搜索</title>
<link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap-theme.min.css">
</head><body class="bs-docs-home">
<div class="container theme-showcase">
<h1 style=" line-height:2em;"></h1><br/> <div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-12">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><strong>ElasticSearch PHP 实战搜索-商品列表</strong></h3>
</div>
<div class="panel-body">
<div class="alert alert-dismissable">
<div class="table-responsive">
<table border="0" cellspacing="0" cellpadding="0" class="table">
<tr class=" label-primary">
<th scope="col" width="20%"><span style="color:white">id</span></th>
<th scope="col"><span style="color:white">商品标题</span></th>
<th scope="col"><span style="color:white">操作</span></th>
</tr>
{foreach $goods as $v}
<tr class="success">
<td>{$v['_source']['id']}</td>
<td>{$v['highlight']['goods_title'][0]|raw}</td>
<td>
<button class="btn btn-default" type="button"
onclick="location.href='/goods/'+{$v['_source']['id']}+'/edit'">编辑
</button>
<button class="btn btn-danger" type="button" onclick="del({$v['_source']['id']})">删除</button>
</td>
</tr>
{/foreach}
</table>
</div>
<div class="col-sm-12"> <div class="col-sm-10"></div>
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="/search?keywords={$keywords}&page={$pre}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li> <li>
<a href="/search?keywords={$keywords}&page={$next}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/js/bootstrap.min.js"></script>
</body>
</html>
<script>
function del(id){
$.ajax({
url:'/goods/'+id,
type:'DELETE',
sueccess:function (res){
console.log(res);
// location.href='/search'
}
});
}
</script>
控制器
D:\phpstudy_pro\WWW\thinkphp6\app\controller\Goods.php
# 引入
use Elasticsearch\ClientBuilder;class Goods
{
public function index()
{
return view('search');
} public function search(Request $request)
{
//与es建立连接
$client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build(); $keywords = $request->param('keywords', '', 'trim'); $page = $request->param('page');
$size = 20;
if ($page) {
$from = ($page - 1) * 20;
$pre = $page - 1;
$next = $page + 1;
} else {
$pre = 1;
$next = 2;
$from = ($pre - 1) * 20;
}
$search = [
'index' => 'goods',
'body' => [
'query' => [
'match' => [
'goods_title' => $keywords
]
],
'from' => $from,
'size' => $size,
'highlight' => [
'fields' => [
'goods_title' => new \stdClass()
],
'pre_tags' => ["<font style='color:red'>"],
'post_tags' => ['</font>']
]
]
];
$res = $client->search($search);
return view('list', ['goods' => $res['hits']['hits'], 'keywords' => $keywords, 'pre' => $pre, 'next' => $next]);
}
}
高亮报错处理:
https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/php_json_objects.html
new \stdClass()
es实战之php添加文档到es
为了保证es和数据库中数据实时同步,在保存数据入mysql同时保存一份在es
添加页面
D:\phpstudy_pro\WWW\thinkphp6\view\goods\add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title>ElasticSearch PHP 实战搜索</title>
<link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap-theme.min.css">
</head><body class="bs-docs-home">
<div class="container theme-showcase">
<h1 style=" line-height:2em;"></h1><br/> <div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-12">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><strong>ElasticSearch PHP 实战搜索-添加商品</strong></h3>
</div>
<div class="panel-body">
<div class="alert alert-dismissable">
<form action="/goods" method="post" role="form" name="form1"> <div class="form-group">
<div class="input-group">
<input type="text" name="goods_title" class="form-control" placeholder="商品标题">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">添加</button>
</span>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-sm-3"></div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/js/bootstrap.min.js"></script>
</body>
</html>
控制器
public function create()
{
return view('add');
}public function save(Request $request)
{
$client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build();
$goods_title = $request->param('goods_title');
$cat_id = 200;
//插入数据库同时插入es
$id = Db::name('goods')->insertGetId(['cat_id'=>$cat_id,'goods_title'=>$goods_title]);
$doc = [
'index'=>'goods',
'id'=>$id,
'body'=>[
'id'=>$id,
'goods_title'=>$goods_title
]
];
$client->index($doc);
return view('search');
}
es实战之php更新文档
更新数据库同时更新es
更新页面
D:\phpstudy_pro\WWW\thinkphp6\view\goods\edit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title>ElasticSearch PHP 实战搜索</title>
<link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap-theme.min.css">
</head><body class="bs-docs-home">
<div class="container theme-showcase">
<h1 style=" line-height:2em;"></h1><br/>
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-12">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><strong>ElasticSearch PHP 实战搜索-编辑商品</strong></h3>
</div>
<div class="panel-body">
<div class="alert alert-dismissable">
<form action="/goods/{$goods['id']}" method="post" role="form" name="form1">
<input type="hidden" name="_method" value="PUT">
<div class="form-group">
<div class="input-group">
<input type="text" name="goods_title" class="form-control"
value="{$goods['goods_title']}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">保存</button>
</span>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-sm-3"></div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://cdn.bootcss.com/twitter-bootstrap/3.0.1/js/bootstrap.min.js"></script>
</body>
</html>
控制器
public function edit($id)
{
$goods = Db::name('goods')->where('id', $id)->find();
return view('edit', ['goods' => $goods]);
}public function update(Request $request, $id)
{
$goods_title = $request->param('goods_title');
//1、更新数据库
Db::name('goods')->where('id', $id)->update(['goods_title' => $goods_title]);
//2、更新es
$client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build(); $doc = [
'index' => 'goods',
'id' => $id,
'body' => [
'doc'=>[
'goods_title' => $goods_title
]
]
]; $client->update($doc);
return view('search');
}
php删除es文档
控制器
public function delete($id)
{
//1、删除数据库id数据
Db::name('goods')->where('id', $id)->delete();
//2、删除es
$client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build();
$client->delete(['index' => 'goods', 'id' => $id]);
return json(['status' => 'success']);
}
发表评论 取消回复