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