js 代码: 通过js 得到去掉前缀的域名

js 代码如下:

<script>
domain = document.domain;
domain = domain.match(/[^\.]*\.[^.]*$/)[0];
</script>

如果当前域名为http://fancyecommerce.com 返回 fancyecommerce.com

如果当前域名为http://www.fancyecommerce.com 返回 fancyecommerce.com

如果当前域名为http://xxxx.fancyecommerce.com 返回 fancyecommerce.com

Yii2 elasticSearch 多值查询 和 查询数组字段

Yii2 elasticSearch 多值查询的例子,相当于关系型数据库的in查询

$should = [];
if(is_array($customers) && !empty($customers)){
  foreach($customers as $one){
    $should[] = ['term' => ['customer_id' => $one['customer_id']]];
  }
}
$filter_arr['bool']['should'] = $should;
$result = $obj::find()->filter($filter_arr)
    ->query($query_arr)
    ->asArray()
    ->limit(0)
    ->offset(33)
    ->all();
$data = BaseArrayHelper::getColumn($result, '_source');

查询数组字段,$filter的定义如下:

$filter_arr = [
        'bool' => [
          'must' => [
            ['term' => ['emails' => $email],]
          ]
        ],
      ];

 

 

elasticSearch 批量传递数据,存在数据丢失的原因

elasticSearch 如果字段要做全量匹配,也就是像mysql那样,而不是分词模糊匹配,那么需要建立mapping   加入not_analysised ,这个可以参考之前的文章。

然后我重新传递数据的时候,发现数据存在丢失,最后找出来了原因:

1.如果是多维数组,那么需要建立mapping,不然无法传递数据,但是如果是一维数组,则没有问题,因此,如果是多维数组,可以序列化成字符串存储

2.如果一个字段定义成string,如果长度太长,几千的字符,那么就会保存不了,长度过长,我就是把多维数组序列化后,长度太长无法保存到elasticSearch中,最后,我把多维数组里面的每一个子项进行序列化,然后以一维数组的方式存储,算是解决了这个问题。

elasticSearch在使用的时候,还是有一些坑,需要多练习,多观察一些数据,是否丢失,是否准确等等。

Yii2 – elasticSearch 新建mapping操作

在一些需要完全匹配,或者其他的一些情况,需要建立mapping,这个有点类似mysql的表定义

ActiveRecord的定义:

<?php

namespace appadmin\code\Ta\models\elasticSearch;

use yii\elasticsearch\ActiveRecord;

class TraceData extends ActiveRecord
{
  public static $currentIndex;
  
  # 定义db链接
  public static function getDb()
  {
    return \Yii::$app->get('elasticsearch_TA');
  }
  
  # 不同的website 使用的是不同的db ,使用前需要先初始化
  # db的名字
  public static function initDb($website_id){
    if($website_id){
      self::$currentIndex = 'ta'."_".$website_id;
    }
  }
  
  
  
  # db
  public static function index()
  {
    return self::$currentIndex;
  }
  # table
  public static function type()
  {
    return 'trace_data';
  }
  
   public function attributes()
    {
        $mapConfig = self::mapConfig();
    return array_keys($mapConfig['properties']);
    }
  
  public static function mapConfig(){
    return [
      'properties' => [
        'id'				=> ['type' => 'string',"index" => "not_analyzed"],
        'ip'				=> ['type' => 'string',"index" => "not_analyzed"],
        'service_date_str'	=> ['type' => 'string',"index" => "not_analyzed"],
        'service_datetime'	=> ['type' => 'string',"index" => "not_analyzed"],
        'service_timestamp'	=> ['type' => 'integer',"index" => "not_analyzed"],
        'devide' 			=> ['type' => 'string',"index" => "not_analyzed"],
        'user_agent' 		=> ['type' => 'string',"index" => "not_analyzed"],
        'browser_name' 		=> ['type' => 'string',"index" => "not_analyzed"],
        'browser_version'	=> ['type' => 'string',"index" => "not_analyzed"],
        'browser_date'		=> ['type' => 'string',"index" => "not_analyzed"],
        'browser_lang'		=> ['type' => 'string',"index" => "not_analyzed"],
        'operate' 			=> ['type' => 'string',"index" => "not_analyzed"],
        'operate_relase'	=> ['type' => 'string',"index" => "not_analyzed"],
        'domain' 			=> ['type' => 'string',"index" => "not_analyzed"],
        'url'				=> ['type' => 'string',"index" => "not_analyzed"],
        'title'				=> ['type' => 'string',"index" => "not_analyzed"],
        'refer_url'			=> ['type' => 'string',"index" => "not_analyzed"],
        'first_referrer_domain'	=> ['type' => 'string',"index" => "not_analyzed"],
        'is_return'			=> ['type' => 'integer',"index" => "not_analyzed"],
        'uuid'				=> ['type' => 'string',"index" => "not_analyzed"],
        'device_pixel_ratio'=> ['type' => 'string',"index" => "not_analyzed"],
        'resolution'		=> ['type' => 'string',"index" => "not_analyzed"],
        'color_depth'		=> ['type' => 'string',"index" => "not_analyzed"],
        'website_id'		=> ['type' => 'integer',"index" => "not_analyzed"],
        'sku'				=> ['type' => 'string',"index" => "not_analyzed"],
        'country_code'		=> ['type' => 'string',"index" => "not_analyzed"],
        'country_name'		=> ['type' => 'string',"index" => "not_analyzed"],
        
        'order_status' 		=> ['type' => 'string',"index" => "not_analyzed"],
        'cart' 				=> ['type' => 'string',"index" => "not_analyzed"],
        'order'				=> ['type' => 'string',"index" => "not_analyzed"],
        'category'			=> ['type' => 'string',"index" => "not_analyzed"],
        'login_email'		=> ['type' => 'string',"index" => "not_analyzed"],
        'register_email'	=> ['type' => 'string',"index" => "not_analyzed"],
        'search'			=> ['type' => 'string',"index" => "not_analyzed"],
        'currency'			=> ['type' => 'string',"index" => "not_analyzed"],
        'url_new'			=> ['type' => 'string',"index" => "not_analyzed"],
        'stay_seconds'		=> ['type' => 'integer',"index" => "not_analyzed"],
        'first_visit_this_url'	=> ['type' => 'string',"index" => "not_analyzed"],
      ]
    ];
  }
  
  public static function mapping()
    {
        return [
            static::type() => self::mapConfig(),
        ];
    }

    /**
     * Set (update) mappings for this model
     */
    public static function updateMapping(){
        $db = self::getDb();
        $command = $db->createCommand();
    if(!$command->indexExists(self::index())){
      $command->createIndex(self::index());
    }
        $command->setMapping(self::index(), self::type(), self::mapping());
    }
  
  public static function getMapping(){
    $db = self::getDb();
        $command = $db->createCommand();
    return $command->getMapping();
  }
  
  
  
}

使用:

public function actionMapping($websiteIds){
    $arr = explode(",",$websiteIds);
    foreach($arr as $website_id){
      TraceData::initDb($website_id);
      TraceData::updateMapping();
      $map = TraceData::getMapping();
      var_dump($map);
    }
}

通过updateMapping来更新mapping

通过getMapping得到定义好的mapping

在这里的一个坑就是:在添加表(type)mapping的时候,需要提前定义Index(相当于mysql的db),才能添加type(相当于表),否则添加不上,或者报错。

其他资料:
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html

http://www.open-open.com/lib/view/open1455452874636.html

Yii2 – 批量插入数据到 elasticSearch

elasticSearch 是目前来说,最强大的开源搜索引擎,对于一些搜索,放到ElasticSearch中,速度会快很多,当然,这个玩意也是非常消耗资源。

下面是,使用yii2,将数据批量导入到ES中,单行插入的效率太低,使用批量插入,速度还是可以。

安装ElasticSearch 这个参看

安装ElasticSearch ,以及在yii2中的使用

2. 安装yii2-ElasticSearch插件

https://github.com/yiisoft/yii2-elasticsearch

3. 配置

'elasticsearch_TA' => [
    'class' => 'yii\elasticsearch\Connection',
    'nodes' => [
        ['http_address' => '192.168.0.199:9200'],
        ['http_address' => '192.168.0.210:9200'],
    ],
],

4.使用

传递数据,我们还是用shell 脚本来传递数据 /appta/shell/customer/syncCustomerDataToEs.sh

#!/bin/sh

DIR=$(cd `dirname $0`; pwd)
# sync mongodb to elasticsearch
echo 'sync custom data to es'
processDate=$1
websiteIds=$2

arr=$(echo $websiteIds|tr "," "\n");
for website_id in $arr; do
  echo "website_id:".$website_id;
  variable=`$DIR/../../../yii ta/migrate/elasticsearch/customerdatapagecount $processDate $website_id`
  echo "$variable.."
  for (( i=1; i<=$variable; i++ ))
  do 
    $DIR/../../../yii ta/migrate/elasticsearch/customerdata $processDate $website_id $i 
    echo "Page $i done"
  done
done







controller文件:

<?php
namespace appadmin\code\Ta\console\migrate;
use Yii;
use appadmin\code\Ta\models\WebsiteBaseInfo;
use yii\console\Controller;
use appadmin\code\Ta\helper\mongoDb as MongoDb;
use appadmin\code\Ta\models\mongo\CustomerData as MgCustomerData;
use appadmin\code\Ta\models\elasticSearch\CustomerData as EsCustomerData;

use appadmin\code\Ta\models\mongo\TraceData as MgTraceData;
use appadmin\code\Ta\models\elasticSearch\TraceData as EsTraceData;


class ElasticsearchController extends Controller
{
  public $numPerPage = 1000;
  //public $dbName = "ta_".$processDate;
  //public $collName;
  
  public function initParam($processDate,$website_id){
    //$thidbName = "ta_".$processDate;
    $collName = "ta_".$website_id."_customer_data";
    //echo $processDate;exit;
    MongoDb::setDbByDate($processDate);
    MgCustomerData::initCollName($website_id);
    MgTraceData::initCollName($website_id);
  }
  # customer data  数据的总页数
  public function actionCustomerdatapagecount($processDate,$website_id){
    $this->initParam($processDate,$website_id);
    $count =  MgCustomerData::find()->count();
    //var_dump(MgCustomerData::getDb());
    //echo $count;exit;
    echo ceil($count/$this->numPerPage);
  }
  # 同步customer data的数据到ElasticSearch
  public function actionCustomerdata($processDate,$website_id,$pageNum){
    $this->initParam($processDate,$website_id);
    $skip = $this->numPerPage * ($pageNum - 1);
    $data = MgCustomerData::find()
        ->asArray()
        ->limit($this->numPerPage)
        ->offset($skip)
        ->all();
    $arr = [];
    $i = 0;
        
    if(is_array($data) && !empty($data )){
      $elasticsearch = Yii::$app->elasticsearch_TA;
      $bulkclient = $elasticsearch->createBulkCommand();
      //EsCustomerData::initDb($website_id);
      $index_name = 'ta_'.$website_id;
      $one_day_type = 'customer_data';
      //$EsCustomerDataOne = EsCustomerData::findOne($a['_id']);
      foreach($data  as $one){
        $i++;
        $a = [];
        $a['id'] = $one['_id'];
        $value = $one['value'];
        if(is_array($value) && !empty($value )){
          foreach($value  as $k => $v){
            if($k == 'data'){
              //var_dump($v);
              $v = serialize($v);
            }
            $a[$k] = $v;
          }
        }
        
        $bulkclient->addAction(array(
          'index' => array(
            '_index'=> $index_name,
            '_type' => $one_day_type,
            '_id' 	=> $one['_id'],
          )
        ), $a);
        /*
        # 保存数据到ES
        EsCustomerData::initDb($website_id);
        $EsCustomerDataOne = EsCustomerData::findOne($a['_id']);
        if(!$EsCustomerDataOne){
          $EsCustomerDataOne = new EsCustomerData;
          $EsCustomerDataOne->setPrimaryKey($a['_id']);
        }
        $EsCustomerDataOne->id = $a['_id'];
        $attributes = $EsCustomerDataOne->attributes();
        foreach($a as $k=>$v){
          if(in_array($k,$attributes)){
            if($k == 'data'){
              //var_dump($v);
              $v = serialize($v);
            }
            $EsCustomerDataOne[$k] = $v;
          }
        }
        $mtime=explode(' ',microtime());
        $startTime=$mtime[1]+$mtime[0];        
        
        $EsCustomerDataOne->save();
        $mtime=explode(' ',microtime());
        $endTime=$mtime[1]+$mtime[0];        
        echo "chaju_time :($i)".($endTime-$startTime)."\n"; 
        //$arr[] = $a; 
        */
      }
      $bulkclient->execute();
    }
    
    
  }
    
  # customer data  数据的总页数
  public function actionTracedatapagecount($processDate,$website_id){
    $this->initParam($processDate,$website_id);
    $count =  MgTraceData::find()->count();
    //var_dump(MgCustomerData::getDb());
    //echo $count;exit;
    echo ceil($count/$this->numPerPage);
  }
  # 同步customer data的数据到ElasticSearch
  public function actionTracedata($processDate,$website_id,$pageNum){
    $this->initParam($processDate,$website_id);
    $skip = $this->numPerPage * ($pageNum - 1);
    $data = MgTraceData::find()
        ->asArray()
        ->limit($this->numPerPage)
        ->offset($skip)
        ->all();
    $arr = [];
    $i = 0;
        
    if(is_array($data) && !empty($data )){
      $elasticsearch = Yii::$app->elasticsearch_TA;
      $bulkclient = $elasticsearch->createBulkCommand();
      //EsCustomerData::initDb($website_id);
      $index_name = 'ta_'.$website_id;
      $one_day_type = 'trace_data';
      //$EsCustomerDataOne = EsCustomerData::findOne($a['_id']);
      foreach($data  as $one){
        $i++;
        $a = [];
        
        if(is_array($one) && !empty($one )){
          foreach($one  as $k => $v){
            $a[$k] = $v;
          }
        }
        $a['id'] = $a['_id'];
        unset($a['_id']);
        
        $bulkclient->addAction(array(
          'index' => array(
            '_index'=> $index_name,
            '_type' => $one_day_type,
            '_id' 	=> $one['_id'],
          )
        ), $a);
        
      }
      $bulkclient->execute();
    }
    
    
  }	
    
    
    
    
    
    
    
    
    
    
    
}

appadmin\code\Ta\models\mongo\CustomerData

<?php  
# 商家SELLER 和  对应的 SELLERID 的设置。 
namespace appadmin\code\Ta\models\mongo; 
use yii\mongodb\ActiveRecord;
use fec\helpers\CDate;
use fec\helpers\CConfig;
use Yii;
use appadmin\code\Ta\helper\mongoDb;
# use appadmin\code\Ta\models\mongo\CustomerData; 
class CustomerData extends ActiveRecord  
{  
  
  public static $_collectionName;
  
  # 定义db
  public static function getDb()
    {
    return \Yii::$app->get('mongodb_ta_date');
    }
  
  
  
  # 定义collection name  
    public static function collectionName()  
    {  
        return self::$_collectionName;  
    }  
  
  
  
  
  public static function initCollName($website_id){
    self::$_collectionName = "ta_".$website_id."_customer_data";
  }
  
  
  public function attributes()
    {
        // path mapping for '_id' is setup to field 'id'
        return [
      '_id', 
      'value',
      
    ];
    }
  
  
}  

appadmin\code\Ta\models\ElasticSearch\CustomerData

<?php

namespace appadmin\code\Ta\models\elasticSearch;

use yii\elasticsearch\ActiveRecord;

class CustomerData extends ActiveRecord
{
  public static $currentIndex;
  
  # 定义db链接
  public static function getDb()
  {
    return \Yii::$app->get('elasticsearch_TA');
  }
  
  # 不同的website 使用的是不同的db ,使用前需要先初始化
  # db的名字
  public static function initDb($website_id){
    //echo 888;
    if($website_id){
      //echo 999;
      self::$currentIndex = 'ta'."_".$website_id;
      //echo self::$currentIndex;
      //echo 3;
    }
  }
  
  
  
  # db
  public static function index()
  {
    return self::$currentIndex;
  }
  # table
  public static function type()
  {
    return 'customer_data';
  }
  
   public function attributes()
    {
        // path mapping for '_id' is setup to field 'id'
        return [
      'id',
      
      'uuid',
      'customer_id',
      'pv',
      
      'ip',
      'service_date_str',
      'service_datetime',
      'service_timestamp',
      'devide',
      'user_agent',
      'browser_name',
      'browser_version',
      'browser_date',
      'browser_lang',
      'operate',
      'operate_relase',
      'domain',
      'url',
      'title',
      'refer_url',
      'first_referrer_domain',
      'is_return',
      'uuid',
      'device_pixel_ratio',
      'resolution',
      'color_depth',
      'website_id',
      'sku',
      'country_code',
      'country_name',
      
      'data',
      
      'order_status',
      'cart',
      'order',
      'category',
      'login_email',
      'register_email',
      'search',
      'currency',
      'stay_seconds',
    ];
    }
  
  
  
}

 

 

linux防火墙 – apf 安装 ,配置,使用

apf是一款比较好用的linxu防火墙,用它来设置iptables等是一个比较好的工具,线上一般免费版,很多使用这个,下面说一下他的安装与配置

wget http://www.rfxn.com/downloads/apf-current.tar.gz  
tar -xvzf apf-current.tar.gz  
cd apf-9.7-2/  
./install.sh  
  
[root@iZ942k2d5ezZ apf-9.7-2]# ./install.sh  
Installing APF 9.7-2: Completed.  
  
Installation Details:  
  Install path:         /etc/apf/  
  Config path:          /etc/apf/conf.apf  
  Executable path:      /usr/local/sbin/apf  
  
Other Details:  
  Listening TCP ports: 22,80,100,3306,6379,27017  
  Listening UDP ports: 123,636  
  Note: These ports are not auto-configured; they are simply presented for information purposes. You must manually configure all port options.

到上面就安装成功了

启动

/etc/init.d/apf start  
chkconfig apf on

二,配置apf

vim /etc/apf/conf.apf   一般按照下面的配置好,然后apf -f(或者apf -r) 刷新一下就行了

IG_TCP_CPORTS="21,22,80,443,3306,8080"   //设置服务器允许被访问的TCP端口    
IG_UDP_CPORTS="53"                       //设置服务器允许被访问的UDP端口    
EG_TCP_CPORTS="21,25,80,443,43,2089"     //设置服务器允许对外访问的TCP端口    
EG_UDP_CPORTS="20,21,53"                 //设置服务器允许对外访问的UDP端口    
   
DEVEL_MODE="1" 改为 DEVEL_MODE="0"    
DLIST_SPAMHAUS="0" 改为 DLIST_SPAMHAUS="1"    
DLIST_DSHIELD="0" 改为 DLIST_DSHIELD="1"

配置过程中要注意以下几点:
1,根据不同的服务器开放不同的端口,web服务器根mysql服务器开放的端口肯定不一样。
2,DEVEL_MODE=”1″表示在调试模式下,每五分钟重调配置,这样能避免因为错误的配置而使服务器崩溃。
3,设置只通许192.168.1.139远程连接22端口

// 在/etc/apf/allow_hosts.rules添加如下信息:    
tcp:in:d=22:s=192.168.1.139    
out:d=22:d=192.168.1.139    
    
// 在/etc/apf/deny_hosts.rules添加如下信息:    
tcp:in:d=22:s=0/0    
out:d=22:d=0/0

开始的时候,我以为只要在allow_hosts.rules里面加就行了,改过一后,我换了一个IP,已然可以连接,搞得我很无语。后在deny_hosts.rules加上了上面的规则后,在连接时就提示超时了。allow_hosts.rules和deny_hosts.rules里面都加了规则后,重起apf会提示配置成功的信息,偶然发现的。

apf(12234): {trust} allow outbound 192.168.1.139 to port 22    
apf(12234): {trust} allow inbound tcp 192.168.1.139 to port 22

三:apf常用命令

apf -s  // 启动APF防火墙    
apf -r  // 重启APF防火墙    
apf -f  // 刷新APF防火墙配置文件    
apf -l  // 列出APF的过虑规则    
apf -t  // APF的日志信息。    
apf -e  // 将域名解释加入信认规则    
apf -a  // 将IP/IP段添加到白名单    
apf -d  // 将IP/IP段添加到黑名单    
apf -u  // 将IP/IP段从白/黑名单中删除    
apf -o  // 将IP/IP段从白/黑名单中删除

常用端口:

21/tcp       //ftp    
22/tcp       //ssh    
25/tcp       //smtp    
53/udp       //dns    
80/tcp       //http    
110/tcp      //pop3    
143/tcp      //imap    
443/tcp      //https    
993/tcp      //imaps    
995/tcp      //pop3    
3306/tcp     //mysql    
5432/tcp     //postgresql

 

其他:
IG_TCP_CPORTS=”21,22,80,443,3306,8080″   //设置服务器允许被访问的TCP端口

IG_UDP_CPORTS=”53″                       //设置服务器允许被访问的UDP端口

EG_TCP_CPORTS=”21,25,80,443,43,2089″     //设置服务器允许对外访问的TCP端口

EG_UDP_CPORTS=”20,21,53″                 //设置服务器允许对外访问的UDP端口

DEVEL_MODE=”1″ 改为 DEVEL_MODE=”0″

DLIST_SPAMHAUS=”0″ 改为 DLIST_SPAMHAUS=”1″

DLIST_DSHIELD=”0″ 改为 DLIST_DSHIELD=”1″

配置过程中要注意以下几点:

1,根据不同的服务器开放不同的端口。

2,DEVEL_MODE=”1″表示在调试模式下,每五分钟重调配置,这样能避免因为错误的配置而使服务器崩溃。

3,设置只通许192.168.1.139远程连接22端口

// 在/etc/apf/allow_hosts.rules添加如下信息:

tcp:in:d=22:s=192.168.1.139

out:d=22:d=192.168.1.139

// 在/etc/apf/deny_hosts.rules添加如下信息:

tcp:in:d=22:s=0/0

out:d=22:d=0/0

开始的时候,我以为只要在allow_hosts.rules里面加就行了,改过一后,我换了一个IP,已然可以连接,搞得我很无语。后在 deny_hosts.rules加上了上面的规则后,在连接时就提示超时了。allow_hosts.rules和deny_hosts.rules里 面都加了规则后,重起apf会提示配置成功的信息,偶然发现的。

apf(12234): {trust} allow outbound 192.168.1.139 to port 22

apf(12234): {trust} allow inbound tcp 192.168.1.139 to port 22

三,apf的常用命令

apf -s  // 启动APF防火墙

apf -r  // 重启APF防火墙

apf -f  // 刷新APF防火墙配置文件

apf -l  // 列出APF的过虑规则

apf -t  // APF的日志信息。

apf -e  // 将域名解释加入信认规则

apf -a  // 将IP/IP段添加到白名单

apf -d  // 将IP/IP段添加到黑名单

apf -u  // 将IP/IP段从白/黑名单中删除

apf -o  // 将IP/IP段从白/黑名单中删除

四,常用端口列表

21/tcp       //ftp

22/tcp       //ssh

25/tcp       //smtp

53/udp       //dns

80/tcp       //http

110/tcp      //pop3

143/tcp      //imap

443/tcp      //https

993/tcp      //imaps

995/tcp      //pop3

3306/tcp     //mysql

5432/tcp     //postgresql

ElasticSearch 使用 – 传递数据规避重复数据

我们一般把mysql的数据,传递到ElasticSearch中,然后进行即使查询,但是ES有一个问题就是,刚刚插入的数据,在1秒内是查询不到的(大致一秒内,粗略的说法),也就是说在很短的时间内,插入一条数据,然后去查询这条数据是查询不到的,因此,我们必须用ES的_id来规避重复数据。

ES中一般除了_id, 再加一个id的字段,用来存储mysql中的id,当然es中的_id也要用mysql中的id来赋值,来规避重复数据。

#通过_id获取数据

$EsTraceDataOne = EsTraceData::findOne($one['_id']);
            if(!$EsTraceDataOne){
                $EsTraceDataOne = new EsTraceData;

# 给Es的表的_id设置值
                $EsTraceDataOne->setPrimaryKey($one['_id']);
            }

# 设置Id
            $EsTraceDataOne->id = $one['_id'];
            $attributes = $EsTraceDataOne->attributes();
            foreach($one as $k=>$v){
                if(in_array($k,$attributes)){

# 只取attributes()方法返回的数组中存在的数据
                    $EsTraceDataOne[$k] = $v;
                }
            }

# 保存
            $EsTraceDataOne->save();

 

通过上面的方法,基本可以规避数据多次传递重复插入数据的问题。

 

附:

<?php

namespace appadmin\code\Ta\models\elasticSearch;

use yii\elasticsearch\ActiveRecord;

class TraceData extends ActiveRecord
{
  public static $currentIndex;
  
  # 定义db链接
  public static function getDb()
  {
    return \Yii::$app->get('elasticsearch_TA');
  }
  
  # 不同的website 使用的是不同的db ,使用前需要先初始化
  # db的名字
  public static function initDb($website_id){
    //echo 888;
    if($website_id){
      //echo 999;
      self::$currentIndex = 'ta'."_".$website_id;
      //echo self::$currentIndex;
      //echo 3;
    }
  }
  
  
  
  # db
  public static function index()
  {
    return self::$currentIndex;
  }
  # table
  public static function type()
  {
    return 'trace_data';
  }
  
   public function attributes()
    {
        // path mapping for '_id' is setup to field 'id'
        return [
      'id',
      'ip',
      'service_date_str',
      'service_datetime',
      'service_timestamp',
      'devide',
      'user_agent',
      'browser_name',
      'browser_version',
      'browser_date',
      'browser_lang',
      'operate',
      'operate_relase',
      'domain',
      'url',
      'title',
      'refer_url',
      'first_referrer_domain',
      'is_return',
      'uuid',
      'device_pixel_ratio',
      'resolution',
      'color_depth',
      'website_id',
      'sku',
      'country_code',
      'country_name',
      
      'order_status',
      'cart',
      'order',
      'category',
      'login_email',
      'register_email',
      'search',
      'currency',
    ];
    }
  
  
  
}

 

安装ElasticSearch ,以及在yii2中的使用

ElasticSearch 是一款优秀的搜索引擎,用java编写,restful接口的方式进行对接。

1. 安装ElasticSearch

安装Java环境
首先检测是否安装java

java -version  
echo $JAVA_HOME

如果java的版本过低,建议安装高版本,下面安装的是java 1.8

cd /opt/    
wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.tar.gz"    
tar xzf jdk-8u66-linux-x64.tar.gz

 

cd /opt/jdk1.8.0_66/    
alternatives --install /usr/bin/java java /opt/jdk1.8.0_66/bin/java 2    
alternatives --config java

运行了上面的,会初选一个选择的地方,我的机器显示:

There are 3 programs which provide 'java'.    
    
  Selection    Command    
-----------------------------------------------    
*  1           /opt/jdk1.7.0_71/bin/java    
 + 2           /opt/jdk1.8.0_45/bin/java    
   3           /opt/jdk1.8.0_51/bin/java    
   4           /opt/jdk1.8.0_66/bin/java    
    
Enter to keep the current selection[+], or type selection number: 4

我们安装的是jdk1.8.0.66 所以,我选择的是4,这个看具体情况,jdk1.8.0.66 是第几个,就选择那个数字。

alternatives --install /usr/bin/jar jar /opt/jdk1.8.0_66/bin/jar 2    
alternatives --install /usr/bin/javac javac /opt/jdk1.8.0_66/bin/javac 2    
alternatives --set jar /opt/jdk1.8.0_66/bin/jar    
alternatives --set javac /opt/jdk1.8.0_66/bin/javac

安装完成,检查版本

java -version    
    
java version "1.8.0_66"    
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)    
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)

保存到文件  /etc/environment中,当服务器重启的时候加载

vi /etc/profile  
  
export JAVA_HOME=/opt/jdk1.8.0_66    
export JRE_HOME=/opt/jdk1.8.0_66/jre    
export PATH=$PATH:/opt/jdk1.8.0_66/bin:/opt/jdk1.8.0_66/jre/bin

重启linux

reboot

查看是否安装成功

java -version  
echo $JAVA_HOME

 

2.

2.1安装ElasticSearch

cd /tools  
wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/zip/elasticsearch/2.4.1/elasticsearch-2.4.1.zip 
unzip elasticsearch-2.4.1.zip 
mv ./elasticsearch-2.4.1 /usr/local/elasticsearch  
cd /usr/local  
groupadd elasticsearch  
useradd -g elasticsearch  elasticsearch  
chown elasticsearch:elasticsearch -R elasticsearch

需要说明的是elasticSearch直接从2,跳成了5版本,5版本刚出来不久,可能不稳定,我建议还是用2版本。

2.2 设置开机启动: 我是本地,直接把iptables 关掉了

vim /etc/rc.d/rc.local  

service iptables stop  
su elasticsearch  -c "/usr/local/elasticsearch/bin/elasticsearch -d"

一定要注意,elasticSearch不能用root账户启动,elasticSearch不能用root账户启动,elasticSearch不能用root账户启动,重要的说三遍。

我这里用的是我新建的elasticsearch账户开机启动

2.3 配置

vim /usr/local/elasticsearch/config/elasticsearch.yml

修改如下:

cluster.name: TA-application  
node.name: node-210  
network.host: 192.168.0.210

其中cluster.name 是集群名称,这个不要使用默认的,要修改,去掉注释,如果有多个机器,加入同一个集群,那么这个值必须一样

noide.name 是集群里面每个节点的值,也就是当前机器的节点的值,这个值,每个节点要不一样。

network host 改成当前的内网ip

2.3  #安装head 插件

su elasticsearch  
  
cd  /usr/local/elasticsearch  
  
bin/plugin install mobz/elasticsearch-head  
  
#启动:  
  
bin/elasticsearch -d

2.4 查看:

http://192.168.0.210:9200/

head插件地址:

http://192.168.0.210:9200/_plugin/head/

2.5 集群设置

如果想要建立一个elasticSearch集群,可以按照下面的步骤,非常的简单,首先,想说明的是:对于elasticSearch,他隐藏了分布式的复杂性,分片和复制集,都是他自动完成,你只需要配置好ip就可以了,下面是配置的步骤:

我有两台机器  192.169.0.210   192.168.0.199

我的两台机器都按照上面的步骤配置完成,下面配置集群

首先是192.168.0.210

vim /usr/local/elasticsearch/config/elasticsearch.yml

#找到行 , 修改如下:

discovery.zen.ping.unicast.hosts: ["192.168.0.199"]

上面的ip就是其他的节点的ip,如果我有5台机器,那么,这里需要把其他四台机器的ip写上。

同理,对于其他的节点,需要把其他的节点协商,用逗号隔开

elasticSearch会找到对应的节点,自动分片和做复制集。

3. 资料片

官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/5.0/_installation.html

入门教程

http://www.jianshu.com/p/f437b893502a

权威指南

http://es.xiaoleilu.com/

 

4.  Elasticsearch集群关闭节点

关闭节点

关闭节点的API允许关闭集群中的一个或多个(或者全部)节点。下面是一个关闭 _local 节点的例子:

$ curl -XPOST 'http://localhost:9200/_cluster/nodes/_local/_shutdown' 

也可以通过各自的节点ID来关闭指定的节点(或者像这里说明 的别的选项):

$ curl -XPOST 'http://localhost:9200/_cluster/nodes/nodeId1,nodeId2/_shutdown' 

集群的主节点也可以使用下面的方法来关闭:

$ curl -XPOST 'http://localhost:9200/_cluster/nodes/_master/_shutdown' 

最后,可以使用如下的任意一种方法来关闭所有的节点:

$ curl -XPOST 'http://localhost:9200/_shutdown' $ curl -XPOST 'http://localhost:9200/_cluster/nodes/_shutdown' $ curl -XPOST 'http://localhost:9200/_cluster/nodes/_all/_shutdown' 

延迟

默认情况下,关闭命令会延迟1秒(1s)之后执行。可以通过设置 delay 参数 来指定延迟的时间。比如:

$ curl -XPOST 'http://localhost:9200/_cluster/nodes/_local/_shutdown?delay=10s' 

禁用关闭命令

关闭的API可以通过设置节点里的 action.disable_shutdown 选项来禁用。

5. Yii2 使用elasticSearch

首先需要安装yii2的elasticSearch插件

https://github.com/yiisoft/yii2-elasticsearch

安装步骤,参看官网的下面的说明,用起来还是不错

里面有聚合功能,可以做一些小规模数据的快速统计。

yii2 elasticSearch的使用说明地址:https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md