我们一般把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', ]; } }