构建该model之前需要自行配置yii2-elasticsearch组件安装
我是通过composer安装的
在composer.json中
安装完成之后
然后需要在yii的配置文件中加入小组件相关配置
接下来就是构建业务模型
集成的ActiveRecord类应该为组件目录下的AR类
use yii\elasticsearch\ActiveRecord
这个AR了重写了yii2的AR类部分方法,有些查询需要原生es语句才可以。
Model:
class HospitalEsModel extends ActiveRecord
{
/**
* 数据库
*/
public static function getDb()
{
return \Yii::$app->get('elasticsearch');
}
/**
* 索引
*/
public static function index()
{
return 'hospital';
}
/**
* 设置索引别名
*/
public static function alias()
{
return 'hospital_new';
}
/**
* 类型
*/
public static function type()
{
return '_doc';
}
/**
* 返回字段
*/
public function attributes()
{
$mapConfig = self::mapConfig();
return array_keys($mapConfig['properties']);
}
/**
* 映射配置
*/
public static function mapConfig()
{
return [
'properties' => [
'id' => ['type' => 'integer'], //医院id
'province_id' => ['type' => 'integer'], //省份ID
'province_name' => ['type' => 'keyword'], //省份名称
'city_id' => ['type' => 'integer'], //城市ID
'city_name' => ['type' => 'keyword'], //城市名称
'district_id' => ['type' => 'integer'], //区县ID
'district_name' => ['type' => 'keyword'],//区县名称
'name' => ['type' => 'text', 'analyzer' => "ik_max_word"], //医院名称
'nick_name' => ['type' => 'text', 'analyzer' => "ik_max_word"], //医院别名
'phone' => ['type' => 'keyword'], //医院电话
'address' => ['type' => 'text', 'analyzer' => "ik_max_word"], //医院地址
'site' => ['type' => 'keyword'], //医院网址
'mail_num' => ['type' => 'keyword'], //邮编
'fax_num' => ['type' => 'keyword'], //传真
'email' => ['type' => 'keyword'], //邮箱
'routes' => ['type' => 'text', 'analyzer' => "ik_max_word"], //路线
'level' => ['type' => 'keyword'], //医院等级文本
'insurance' => ['type' => 'keyword'], //是否保险
'type' => ['type' => 'keyword'], //类型:综合、专科
'kind' => ['type' => 'keyword'], //性质:公立、私立
'tsks' => ['type' => 'text', 'analyzer' => "ik_max_word"], //特色
'photo' => ['type' => 'keyword'], //头图
'photo_list' => ['type' => 'text'], //图片列表
'description' => ['type' => 'text', 'analyzer' => "ik_max_word"], //简介
'city_uri' => ['type' => 'keyword'],//城市URI
'page_uri' => ['type' => 'keyword'], //页面URI
'url' => ['type' => 'keyword'], //医院网址
'is_shequ' => ['type' => 'integer'], //是否是社区服务站
'insurance_num' => ['type' => 'keyword'], //医保编码
'display_order' => ['type' => 'integer'], //显示顺序
'status' => ['type' => 'byte'], //状态, 0正常, 1未审核
'level_num' => ['type' => 'integer'], //医院等级对应数字
'store_id' => ['type' => 'integer'], //药店ID
'score' => ['type' => 'integer'], //综合评分
'source' => ['type' => 'keyword'], //来源
'fudan_score' => ['type' => 'integer'], //复旦大学医院综合评分
]
];
}
/**
* 设置映射
*/
public static function mapping()
{
return self::mapConfig();
}
/**
* 获取映射
*/
public static function getMapping()
{
$db = self::getDb();
$command = $db->createCommand();
return $command->getMapping(static::index());
}
/**
* 更新映射
*/
public static function updateMapping()
{
$db = self::getDb();
$command = $db->createCommand();
if (!$command->indexExists(self::index() . '_' . date('d'))) {
return $command->createIndex(self::index() . '_' . date('d'), [
'mappings' => static::mapping(),
]);
}else{
return $command->setMapping(self::index() . '_' . date('d'), '', self::mapping());
}
}
/**
* 更新别名指向
*/
public static function updateAlias()
{
$db = self::getDb();
$command = $db->createCommand();
$alias = $command->getAliasInfo();
$currentIndex = key($alias);
$result = $command->addAlias(self::index() . '_' . date('d'), self::alias());
if ($currentIndex) {
$result = $command->removeAlias($currentIndex, self::alias());
}
return $result;
}
/**
* 创建索引
*/
public static function createIndex()
{
$db = static::getDb();
$command = $db->createCommand();
$result = $command->createIndex(static::index(), [
'mappings' => static::mapping(),
]);
return $result;
}
/**
* 删除索引
*/
public static function deleteIndex()
{
$db = static::getDb();
$command = $db->createCommand();
$result = $command->deleteIndex(static::index());
return $result;
}
/**
* 获取医院详情
*/
public function getDetail($hospital_id, $fields = [])
{
if (!empty($fields)) {
return self::find()->select($fields)->where(['id' => $hospital_id])->asArray()->one();
}
return self::find()->where(['id' => $hospital_id])->asArray()->one();
}
/**
* 获取医院等级数据
*/
private function getHospitalLevel($level_id)
{
$level_base = json_decode(\Yii::$app->redis->get('yuanxin:base:data:sundry'), true);
if (empty($level_base) || !is_array($level_base)) {
return '';
}
return isset($level_base[1][$level_id]) ? $level_base[1][$level_id] : '';
}
/**
* 根据医生ID将医生数据插入ES中
*/
public function insertToEs($hospital_id)
{
$hospitalInfo = DoctorHospitals::find()->where(['id' => $hospital_id])->asArray()->one();
if (!empty($hospitalInfo)) {
//医院等级文本
$hospital_level_text = $this->getHospitalLevel($hospitalInfo['level_num']);
try {
$hospitalEsModel = new self();
$hospitalEsModel->setPrimaryKey($hospitalInfo['id']);
$hospitalEsModel->setAttribute('id', $hospital_id);
$hospitalEsModel->setAttribute('province_id', trim($hospitalInfo['province_id']));
$hospitalEsModel->setAttribute('province_name', $this->filterText($hospitalInfo['province_name']));
$hospitalEsModel->setAttribute('city_id', trim($hospitalInfo['city_id']));
$hospitalEsModel->setAttribute('city_name', $this->filterText($hospitalInfo['city_name']));
$hospitalEsModel->setAttribute('district_id', $hospitalInfo['district_id']);
$hospitalEsModel->setAttribute('district_name', $this->filterText($hospitalInfo['district_name']));
$hospitalEsModel->setAttribute('name', $this->filterText($hospitalInfo['name']));
$hospitalEsModel->setAttribute('nick_name', $this->filterText($hospitalInfo['nick_name']));
$hospitalEsModel->setAttribute('phone', $this->filterText($hospitalInfo['phone']));
$hospitalEsModel->setAttribute('address', $this->filterText($hospitalInfo['address']));
$hospitalEsModel->setAttribute('site', $this->filterText($hospitalInfo['site']));
$hospitalEsModel->setAttribute('mail_num', $this->filterText($hospitalInfo['mail_num']));
$hospitalEsModel->setAttribute('fax_num', $this->filterText($hospitalInfo['fax_num']));
$hospitalEsModel->setAttribute('email', $this->filterText($hospitalInfo['email']));
$hospitalEsModel->setAttribute('routes', $this->filterText($hospitalInfo['routes']));
$hospitalEsModel->setAttribute('level', $this->filterText($hospital_level_text));
$hospitalEsModel->setAttribute('insurance', $this->filterText($hospitalInfo['insurance']));
$hospitalEsModel->setAttribute('type', $this->filterText($hospitalInfo['type']));
$hospitalEsModel->setAttribute('kind', $this->filterText($hospitalInfo['kind']));
$hospitalEsModel->setAttribute('tsks', $this->filterText($hospitalInfo['tsks']));
$hospitalEsModel->setAttribute('photo', $this->filterText($hospitalInfo['photo']));
$hospitalEsModel->setAttribute('photo_list', $this->filterText($hospitalInfo['photo_list']));
$hospitalEsModel->setAttribute('description', $this->filterText($hospitalInfo['description']));
$hospitalEsModel->setAttribute('city_uri', $this->filterText($hospitalInfo['city_uri']));
$hospitalEsModel->setAttribute('page_uri', $this->filterText($hospitalInfo['page_uri']));
$hospitalEsModel->setAttribute('url', $this->filterText($hospitalInfo['url']));
$hospitalEsModel->setAttribute('is_shequ', $this->filterText($hospitalInfo['is_shequ']));
$hospitalEsModel->setAttribute('insurance_num', $this->filterText($hospitalInfo['insurance_num']));
$hospitalEsModel->setAttribute('display_order', intval($hospitalInfo['display_order']));
$hospitalEsModel->setAttribute('status', intval($hospitalInfo['status']));
$hospitalEsModel->setAttribute('level_num', intval($hospitalInfo['level_num']));
$hospitalEsModel->setAttribute('store_id', intval($hospitalInfo['store_id']));
$hospitalEsModel->setAttribute('score', intval($hospitalInfo['score']));
$hospitalEsModel->setAttribute('source', strval($hospitalInfo['source']));
$hospitalEsModel->setAttribute('fudan_score', intval($hospitalInfo['fudan_score']));
$hospitalEsModel->save();
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage()];
}
} else {
return ['code' => 0, 'msg' => '医院不存在,插入ES失败!'];
}
return ['code' => 1, 'msg' => '医院信息插入ES成功!'];
}
/**
* 更新ES中医生数据
*/
public function updateToEs($hospital_id)
{
$hospitalEsModel = self::get($hospital_id);
//如果不存在就插入ES
if (is_null($hospitalEsModel)) {
return $this->insertToEs($hospital_id);
} else {
$hospitalInfo = DoctorHospitals::find()->where(['id' => $hospital_id])->asArray()->one();
//医院等级文本
$hospital_level_text = $this->getHospitalLevel($hospitalInfo['level_num']);
try {
$hospitalEsModel->setAttribute('province_id', trim($hospitalInfo['province_id']));
$hospitalEsModel->setAttribute('province_name', $this->filterText($hospitalInfo['province_name']));
$hospitalEsModel->setAttribute('city_id', trim($hospitalInfo['city_id']));
$hospitalEsModel->setAttribute('city_name', $this->filterText($hospitalInfo['city_name']));
$hospitalEsModel->setAttribute('district_id', $hospitalInfo['district_id']);
$hospitalEsModel->setAttribute('district_name', $this->filterText($hospitalInfo['district_name']));
$hospitalEsModel->setAttribute('name', $this->filterText($hospitalInfo['name']));
$hospitalEsModel->setAttribute('nick_name', $this->filterText($hospitalInfo['nick_name']));
$hospitalEsModel->setAttribute('phone', $this->filterText($hospitalInfo['phone']));
$hospitalEsModel->setAttribute('address', $this->filterText($hospitalInfo['address']));
$hospitalEsModel->setAttribute('site', $this->filterText($hospitalInfo['site']));
$hospitalEsModel->setAttribute('mail_num', $this->filterText($hospitalInfo['mail_num']));
$hospitalEsModel->setAttribute('fax_num', $this->filterText($hospitalInfo['fax_num']));
$hospitalEsModel->setAttribute('email', $this->filterText($hospitalInfo['email']));
$hospitalEsModel->setAttribute('routes', $this->filterText($hospitalInfo['routes']));
$hospitalEsModel->setAttribute('level', $this->filterText($hospital_level_text));
$hospitalEsModel->setAttribute('insurance', $this->filterText($hospitalInfo['insurance']));
$hospitalEsModel->setAttribute('type', $this->filterText($hospitalInfo['type']));
$hospitalEsModel->setAttribute('kind', $this->filterText($hospitalInfo['kind']));
$hospitalEsModel->setAttribute('tsks', $this->filterText($hospitalInfo['tsks']));
$hospitalEsModel->setAttribute('photo', $this->filterText($hospitalInfo['photo']));
$hospitalEsModel->setAttribute('photo_list', $this->filterText($hospitalInfo['photo_list']));
$hospitalEsModel->setAttribute('description', $this->filterText($hospitalInfo['description']));
$hospitalEsModel->setAttribute('city_uri', $this->filterText($hospitalInfo['city_uri']));
$hospitalEsModel->setAttribute('page_uri', $this->filterText($hospitalInfo['page_uri']));
$hospitalEsModel->setAttribute('url', $this->filterText($hospitalInfo['url']));
$hospitalEsModel->setAttribute('is_shequ', $this->filterText($hospitalInfo['is_shequ']));
$hospitalEsModel->setAttribute('insurance_num', trim($hospitalInfo['insurance_num']));
$hospitalEsModel->setAttribute('display_order', intval($hospitalInfo['display_order']));
$hospitalEsModel->setAttribute('status', intval($hospitalInfo['status']));
$hospitalEsModel->setAttribute('level_num', intval($hospitalInfo['level_num']));
$hospitalEsModel->setAttribute('store_id', intval($hospitalInfo['store_id']));
$hospitalEsModel->setAttribute('score', intval($hospitalInfo['score']));
$hospitalEsModel->setAttribute('source', strval($hospitalInfo['source']));
$hospitalEsModel->setAttribute('fudan_score', intval($hospitalInfo['fudan_score']));
$hospitalEsModel->save();
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage()];
}
return ['code' => 1, 'msg' => '医院更新ES成功!'];
}
}
/**
* 从ES中删除数据
*/
public function deleteFromEs($hospital_id)
{
return self::find()->where(['id' => $hospital_id])->delete();
}
/**
* 初始化时跑数据
*/
public function initEsData($hospital_id){
$hospitalInfo = DoctorHospitals::find()->where(['id' => $hospital_id])->asArray()->one();
//医院等级文本
$hospital_level_text = $this->getHospitalLevel($hospitalInfo['level_num']);
//组合数据
$data = [];
$data['id'] = $hospital_id;
$data['province_id'] = intval($hospitalInfo['province_id']);
$data['province_name'] = $this->filterText($hospitalInfo['province_name']);
$data['city_id'] = intval($hospitalInfo['city_id']);
$data['city_name'] = $this->filterText($hospitalInfo['city_name']);
$data['district_id'] = intval($hospitalInfo['district_id']);
$data['district_name'] = $this->filterText($hospitalInfo['district_name']);
$data['name'] = $this->filterText($hospitalInfo['name']);
$data['nick_name'] = $this->filterText($hospitalInfo['nick_name']);
$data['phone'] = $this->filterText($hospitalInfo['phone']);
$data['address'] = $this->filterText($hospitalInfo['address']);
$data['site'] = $this->filterText($hospitalInfo['site']);
$data['mail_num'] = $this->filterText($hospitalInfo['mail_num']);
$data['fax_num'] = $this->filterText($hospitalInfo['fax_num']);
$data['email'] = $this->filterText($hospitalInfo['email']);
$data['routes'] = $this->filterText($hospitalInfo['routes']);
$data['level'] = $this->filterText($hospital_level_text);
$data['insurance'] = $this->filterText($hospitalInfo['insurance']);
$data['type'] = $this->filterText($hospitalInfo['type']);
$data['kind'] = $this->filterText($hospitalInfo['kind']);
$data['tsks'] = $this->filterText($hospitalInfo['tsks']);
$data['photo'] = $this->filterText($hospitalInfo['photo']);
$data['photo_list'] = $this->filterText($hospitalInfo['photo_list']);
$data['description'] = $this->filterText($hospitalInfo['description']);
$data['city_uri'] = $this->filterText($hospitalInfo['city_uri']);
$data['page_uri'] = $this->filterText($hospitalInfo['page_uri']);
$data['url'] = $this->filterText($hospitalInfo['url']);
$data['is_shequ'] = $this->filterText($hospitalInfo['is_shequ']);
$data['insurance_num'] = $this->filterText($hospitalInfo['insurance_num']);
$data['display_order'] = intval($hospitalInfo['display_order']);
$data['status'] = intval($hospitalInfo['status']);
$data['level_num'] = intval($hospitalInfo['level_num']);
$data['store_id'] = intval($hospitalInfo['store_id']);
$data['score'] = intval($hospitalInfo['score']);
$data['source'] = intval($hospitalInfo['source']);
$data['fudan_score'] = intval($hospitalInfo['fudan_score']);
$db = self::getDb();
$command = $db->createCommand();
$res = $command->insert(self::index().'_'.date('d'), '_doc', $data, $hospital_id);
return $res;
}
/**
* 过滤文本
*/
private function filterText($content)
{
//过滤标签空格
$contentStr = preg_replace("/(\s|\ \;| |\xc2\xa0)/", "", strip_tags($content));
//过滤字符串中的\r\n 以及转义字符
$contentStr = stripslashes(str_replace(array("\r\n", "\r", "\n"), "", $contentStr));
return strval(trim($contentStr));
}
}
具体实现效果:
https://wenzheng.blog.csdn.net/article/details/116135276