ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
文档:https://www.elastic.co/guide/cn/elasticsearch/php/current/_overview.html
https://www.elastic.co/cn/virtual-events/getting-started-elasticsearch
Elasticsearch Clients:https://www.elastic.co/guide/en/elasticsearch/client/index.html
other:
如果未指定主机,客户端将尝试连接到localhost:9200.
主机配置
$hosts = [ '192.168.1.1:9200', // IP + Port '192.168.1.2', // Just IP 'mydomain.server.com:9201', // Domain + Port 'mydomain2.server.com', // Just Domain 'https://localhost', // SSL to localhost 'https://192.168.1.3:9200' // SSL to IP + Port ]; $client = ClientBuilder::create() // Instantiate a new ClientBuilder ->setHosts($hosts) // Set the hosts ->build(); // Build the client object
使用 composer require 'elasticsearch/elasticsearch' 来下载到自己项目里
[root@bogon ~]# /usr/local/nginx/html [root@bogon html]# chmod -R 777 www.es.com/ [root@bogon html]# su cc [cc@bogon html]$ cd www.es.com/ [cc@bogon www.es.com]$ composer require 'elasticsearch/elasticsearch' [cc@bogon www.es.com]# ls composer.json composer.lock vendor
1、创建索引文档
<?php require 'vendor/autoload.php'; $client = Elastic\Elasticsearch\ClientBuilder::create()->build(); $params = [ 'index' => 'test_index' , 'id' => 'my_id' , 'body' => [ 'testField' => 'abc' ] ]; $response = $client->index($params); echo "<pre>"; print_r($response->asArray()); # 输出结果: [root@bogon www.es.com]# php test.php <pre>Array ( [_index] => test_index [_id] => my_id3 [_version] => 2 [result] => updated [_shards] => Array ( [total] => 1 [successful] => 1 [failed] => 0 ) [_seq_no] => 3 [_primary_term] => 1 )
2、查看当前 test_index 索引所有文档
[root@bogon www.es.com]# curl http://localhost:9200/_cat/indices?v #类似mysql的show tables health status index uuid pri rep docs.count docs.deleted store.size pri.store.size dataset.size green open test_index 9a_38WOAQSO3IFx2CO71Uw 1 0 4 0 14kb 14kb 14kb [root@bogon www.es.com]# curl -X GET "http://localhost:9200/test_index/_search?pretty=true" { "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 4, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ { "_index" : "test_index", "_id" : "my_id", "_score" : 1.0, "_source" : { "testField" : "abc" } }, { "_index" : "test_index", "_id" : "my_id3", "_score" : 1.0, "_source" : { "testField" : "abd" } }, { "_index" : "test_index", "_id" : "my_id2", "_score" : 1.0, "_source" : { "testField" : "edf" } }, { "_index" : "test_index", "_id" : "my_id4", "_score" : 1.0, "_source" : { "testField" : "asdfg" } } ] } }
3、获取文档
让我们获取刚刚索引的文档。
<?php require 'vendor/autoload.php'; $client = Elastic\Elasticsearch\ClientBuilder::create()->build(); $params = [ 'index' => 'test_index' , 'id' => 'my_id4' ]; $response = $client->get($params); echo "<pre>"; print_r($response->asArray()); # 输出结果: [root@bogon www.es.com]# php test.php <pre>Array ( [_index] => test_index [_id] => my_id4 [_version] => 1 [_seq_no] => 4 [_primary_term] => 1 [found] => 1 [_source] => Array ( [testField] => asdfg ) )
4、搜索文档
<?php require 'vendor/autoload.php'; $client = Elastic\Elasticsearch\ClientBuilder::create()->build(); $params = [ 'index' => 'test_index', 'body' => [ 'query' => [ 'match' => [ 'testField' => 'abc' ] ] ] ]; $response = $client->search($params); echo "<pre>"; print_r($response->asArray()); 输出结果: [root@bogon www.es.com]# php test.php <pre>Array ( [took] => 109 [timed_out] => [_shards] => Array ( [total] => 1 [successful] => 1 [skipped] => 0 [failed] => 0 ) [hits] => Array ( [total] => Array ( [value] => 1 [relation] => eq ) [max_score] => 1.2039728 [hits] => Array ( [0] => Array ( [_index] => test_index [_id] => my_id [_score] => 1.2039728 [_source] => Array ( [testField] => abc ) ) ) ) )
5、删除文档
<?php require 'vendor/autoload.php'; $client = Elastic\Elasticsearch\ClientBuilder::create()->build(); $params = [ 'index' => 'test_index' , 'id' => 'my_id' ]; $response = $client->delete($params); echo "<pre>"; print_r($response->asArray()); # 输出结果 [root@bogon www.es.com]# php test.php <pre>Array ( [_index] => test_index [_id] => my_id [_version] => 2 [result] => deleted [_shards] => Array ( [total] => 1 [successful] => 1 [failed] => 0 ) [_seq_no] => 5 [_primary_term] => 1 )
6、删除索引
<?php require 'vendor/autoload.php'; $client = Elastic\Elasticsearch\ClientBuilder::create()->build(); $deleteParams = [ 'index' => 'test_index' ]; $response = $client->indices()->delete($deleteParams); echo "<pre>"; print_r($response->asArray()); # 输出结果: [root@bogon www.es.com]# php test.php <pre>Array ( [acknowledged] => 1 ) #再次执行 curl test_index 索引
7、创建索引
<?php require 'vendor/autoload.php'; $client = Elastic\Elasticsearch\ClientBuilder::create()->build(); $params = [ 'index' => 'test_index', 'body' => [ 'settings' => [ 'number_of_shards' => 2, 'number_of_replicas' => 0 ] ] ]; $response = $client->indices()->create($params); echo "<pre>"; print_r($response->asArray()); # 输出结果 [root@bogon www.es.com]# php test.php <pre>Array ( [acknowledged] => 1 [shards_acknowledged] => 1 [index] => test_index )
8、文档排序
require 'vendor/autoload.php'; $client = Elastic\Elasticsearch\ClientBuilder::create()->build(); $params = [ 'index' => 'user', 'body' => [ 'query' => [ 'match' => [ 'username' => 'ck' ] ], 'sort' => [ 'age' => [ 'order' => 'desc' ] ] ] ]; $response = $client->search($params); echo "<pre>"; print_r($response->asArray());
单点 ,创建索引时 es 报错:current.health="RED" message="Cluster health status changed from [YELLOW] to [RED] (reason: [reconcile-desired-balance])." previous.health="YELLOW" reason="reconcile-desired-balance"。
查看es的健康状态:http://192.168.241.142:9200/_cat/health?v status是红色。
http://192.168.241.142:9200/_cat/shards , 可以看到某些索引对应的分片是UNASSIGNED(未分片)状态。经多方百度,得到解决方案:
修改索引settings的number_of_replicas为0即可。 原因:分片太多,节点不够。单机es,1个节点但分片的副本数超过1个了,每个主分片的副本数少于群集中的节点数,所以要调整为0。
[root@bogon www.es.com]$ curl -XPUT http://192.168.241.142:9200/_settings?pretty -d "{ \"index\": { \"number_of_replicas\": 0 } }" -H "Content-Type: application/json" { "acknowledged" : true }
刷新 es健康状态,status 变成green.
mysql数据批量导入到elasticsearch
PHP操作es文档位置:https://www.elastic.co/guide/cn/elasticsearch/php/current/_indexing_documents.html
我数据库里面有1378W条数据,需要插入到elasticsearch
jvm.options的配置:-Xms1g -Xmx1g只给了1GB内存,数据库还是用的mysql5.5机械盘,还固态盘的话估计会快一点.
每次从数据库读取3W条数据,然后插入到elasticsearch,从数据库获取数据到插入到elasticsearch,其中获取3W条数据大约是0.5-0.7秒一次,获取数据+插入到elasticsearch的平均是2.5W条/秒
/** * mysql数据批量插入数据到elasticsearch written:yangxingyi * 文档位置:https://www.elastic.co/guide/cn/elasticsearch/php/current/_indexing_documents.html */ public function mysql2esAction(){ ini_set("memory_limit","4048M"); $start = time(); $hosts = [ 'http://elastic:changeme@localhost:9200', ]; $client = ClientBuilder::create()->setHosts($hosts)->build(); //从mysql获取数据 $field = "ID_CDKEY_ORDER,PRODUCTS_NAME,STAMP,EMAIL,BESTELLWERT"; $count = Db::name("cdkey_order")->count(); p($count); $limit = 30000; $prevId = 0; for($i=1;$i<=ceil($count/$limit);$i++){ echo ($i-1)*$limit.PHP_EOL; if($i==1){ $data = Db::name("cdkey_order")->field($field)->limit(0,$limit)->select(); }else{ $data = Db::name("cdkey_order")->where("ID_CDKEY_ORDER",">",$prevId)->field($field)->limit(0,$limit)->select(); } if(!$data){ break; } $params['index'] = 'cdkey_order';//poetry这个document foreach($data as $k=>$v){ $params['body'][]=array( 'index' => array( //id我这里用的是数据库的自增id '_id'=>$v['ID_CDKEY_ORDER'] ), ); $params['body'][] = array( 'product_name'=>$v['PRODUCTS_NAME'], 'stamp'=>$v['STAMP'], 'email'=>$v['EMAIL'], 'amout'=>$v['BESTELLWERT'], ); } $prevId = $v["ID_CDKEY_ORDER"];//获取最后一个customer_id $res = $client->bulk($params); unset($params);//用完这个变量要删除掉,不然这个标量会变得非常大 } }
问题1:
ES集群的健康值是 red 状态. 删除之前 脏数据的索引。
[root@bogon www.es.com]# curl GET http://192.168.241.142:9200/_cluster/health?level=indices { "cluster_name": "elasticsearch", "status": "red", "timed_out": false, "number_of_nodes": 1, "number_of_data_nodes": 1, "active_primary_shards": 0, "active_shards": 0, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 3, "delayed_unassigned_shards": 0, "number_of_pending_tasks": 0, "number_of_in_flight_fetch": 0, "task_max_waiting_in_queue_millis": 0, "active_shards_percent_as_number": 0.0, "indices": { "my_index": { "status": "red", "number_of_shards": 1, "number_of_replicas": 1, "active_primary_shards": 0, "active_shards": 0, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 2 } } }
解决方法,删除这条索引数据(这条数据是楼主排查问题期间产生的脏数据,索引直接删除)
[root@bogon www.es.com]# curl -XDELETE 'http://192.168.241.141:9200/my_index' {"acknowledged":true}
刷新 es 健康状态。
ES查询语法,请参考:Elasticsearch查询语法,只要将ES查询语法转换成PHP数组即可
参考:
实战!聊聊PHP如何使用 ElasticSearch 做搜索
[精选] PHP操作ElasticSearch搜索引擎,一整个流程都在这了
入门:
问题:
单机elasticsearch es 数据迁移健康状态一直是黄色问题解决
本文为崔凯原创文章,转载无需和我联系,但请注明来自冷暖自知一抹茶ckhttp://www.cksite.cn