做的一个项目,数据是从es获取的,所以最近研究了下yii2.0和es.
yii2.0有自身带有一个扩展 yii-elasticsearch.php,在配置的时候
config->web.php中配置
'elasticsearch' => [ 'class' => 'yiielasticsearchConnection', 'is_conversion_net_ip' => true, 'conversion_ips' => [ '127.0.0.1' => '127.0.0.3', '127.0.0.2' => '127.0.0.4', ],
//这两个配置是修改yii2.0扩展中的connection.php,有内网ip的节点的时候yii会返回内网的节点报错,添加这一步是为了转换。 研究好久不知道哪里的问题最后请大神来帮忙解决的。。。。 'nodes' => [ ['http_address' => 'inet[/127.0.0.3:9202]'], ['http_address' => '127.0.0.1:9201'], ['http_address' => '127.0.0.2:9202'], ], ],
配置完成之后,在浏览器可以追踪bug,配置文件里这样配置就好
if (YII_ENV_DEV) { // configuration adjustments for 'dev' environment $config['bootstrap'][] = 'debug'; $config['modules']['debug'] = [ 'class' => 'yiidebugModule', 'panels' => [ 'elasticsearch' => [ 'class' => 'yiielasticsearchDebugPanel', ], ], // uncomment the following to add your IP if you are not connecting from localhost. //'allowedIPs' => ['127.0.0.1', '::1'], ]; }
这样在查询es的时候,可以看到最后生成的es查询语句。这样配置文件就完成了。下面是用es查询
在models新建了一个类 index_type_relation.php
<?php namespace appmodels; use Yii; use yiielasticsearchActiveRecord;//使用activerecord类 use yiihelpersArrayHelper; class Index_type_relation extends ActiveRecord { // # db public static function index() { return "bi_cq"; //类似连接的库 } //# table public static function type() { return "index_type_relation";//类似表 } public function attributes() { return ['index_name_s','index_create_type_s','type_name_s'];//返回表的那些字段 } }
上面是查询一个index,一个type的设置。在controller中的
use appmodelsIndex_type_relation; /** * 获取index_type_relation */ public function get_mapping(){ $relation = new Index_type_relation(); $relation = $relation->find()->limit(10000)->all(); $data = ArrayHelper::toArray($relation); $map_arr = array(); foreach ($data as $k=>$val){ $map_arr[$val['type_name_s']] = $val; } return $map_arr; }
上面是一个index,一个type的查询实例,es支持多个index,多个type的查询,感觉这个很强大,mysql几次查库es一个查询语句搞定
这个没有用activeRecord(没有研究出来怎么用),用的是Query类,写了一个index_query_data类,继承query,使用自带的from()、where()、limit()等
use yiielasticsearchQuery; class Index_data_query extends Query { /* * 日基础信息查询 */ public function get_index_data(&$index_arr, &$table_arr, &$conditons) { //$this->from($index_arr,$table_arr)->where($conditons)->addOrderBy('data_date asc')->limit(10000); $data_key = array( "date_histogram"=>array( "field" =>"data_date", "interval" => "1d", ), "aggregations" =>array( "_type" => array( "terms" => array( "field" => "_type", "size" =>10000 ), "aggregations" => array( "total_l" =>array( "sum" => array( "field" => "total_l" ), ), ), ) ) ); $this->from($index_arr,$table_arr)->where($conditons)->addAggregate('data_date',$data_key)->addOrderBy('data_date asc')->limit(0); $command = $this->createCommand(); $rows = $command->search([],'post'); $data_arr = $rows['aggregations']['data_date']['buckets']; return $data_arr; } }
中间出现一个问题,yii框架是默认使用的get查询方式,带有聚合的查询出来是源数据形式,所以修改了yii组件的search()方法。默认是get,传post就用post的方式。
目前为止,需要的数据都可以从es获取,其中感觉很有意思是聚合,类似mysql的groupby等。
注:查询源数据不设置limit()的时候es默认是10条,最大是10000,所以查询源数据设置limit(10000),带有聚合的可以设置limit(0),这样既提高查询速度,符合条件的也都可以查出来。
以上是边学习yii边实践,所以有学习不到位的地方,希望大家指正修改。