# 酒店职位数据和酒店集团品牌数据Neo4j同步程序

## 概述

`parse_neo4j_process.py` 是一个Python程序，用于将PostgreSQL数据库中的酒店职位数据和酒店集团品牌数据同步到Neo4j图数据库中。

## 功能特性

- 自动读取PostgreSQL数据库中的酒店职位数据和酒店集团品牌数据
- 将部门信息、职位信息、级别信息、集团信息、品牌信息、品牌级别信息同步到Neo4j图数据库的DataLabel节点
- 创建节点之间的层次关系
- 避免重复添加相同名称的节点
- 完整的日志记录和错误处理
- 支持开发和生产环境配置

## 数据同步规则

### 源数据

#### 酒店职位数据 (hotel_positions)
- 数据源：PostgreSQL数据库表 `dataops/public/hotel_positions`
- 查询条件：`status = 'active'` 且 `department_zh`、`position_zh`、`level_zh` 都不为空
- 获取字段：
  - `department_zh`（部门中文名称）、`department_en`（部门英文名称）
  - `position_zh`（职位中文名称）、`position_en`（职位英文名称）
  - `level_zh`（级别中文名称）、`level_en`（级别英文名称）

#### 酒店集团品牌数据 (hotel_group_brands)
- 数据源：PostgreSQL数据库表 `dataops/public/hotel_group_brands`
- 查询条件：`status = 'active'` 且 `group_name_zh`、`brand_name_zh`、`positioning_level_zh` 都不为空
- 获取字段：
  - `group_name_zh`（集团中文名称）、`group_name_en`（集团英文名称）
  - `brand_name_zh`（品牌中文名称）、`brand_name_en`（品牌英文名称）
  - `positioning_level_zh`（定位级别中文名称）、`positioning_level_en`（定位级别英文名称）

### 目标节点
- 节点标签：`DataLabel`
- 节点属性：
  - `name`: 对应字段值（department_zh/position_zh/level_zh/group_name_zh/brand_name_zh/positioning_level_zh）
  - `en_name`: 对应英文名称（department_en/position_en/level_en/group_name_en/brand_name_en/positioning_level_en）
  - `describe`: 空字符串
  - `time`: 当前系统时间
  - `category`: "人才地图"
  - `status`: "active"
  - `node_type`: 节点类型（department/position/position_level/group/brand/brand_level）

### 节点关系

#### 酒店职位关系
- **BELONGS_TO**: 职位节点 → 部门节点（表示职位属于某个部门）
- **HAS_LEVEL**: 职位节点 → 级别节点（表示职位具有某个级别）

#### 酒店集团品牌关系
- **BELONGS_TO**: 品牌节点 → 集团节点（表示品牌属于某个集团）
- **HAS_LEVEL**: 品牌节点 → 品牌级别节点（表示品牌具有某个定位级别）

### 去重逻辑
- 在创建新节点前，检查Neo4j中是否已存在相同 `name` 的DataLabel节点
- 如果存在，则跳过该记录，不重复创建
- 关系使用MERGE操作，避免重复创建

## 使用方法

### 1. 直接运行

```bash
# 在项目根目录下运行
python app/core/data_parse/parse_neo4j_process.py
```

### 2. 作为模块导入

```python
from app.core.data_parse.parse_neo4j_process import HotelPositionNeo4jProcessor

# 创建处理器实例
processor = HotelPositionNeo4jProcessor()

# 运行同步程序
success = processor.run()
```

## 环境要求

### 依赖包
- `neo4j>=5.0.0` - Neo4j Python驱动
- `psycopg2-binary>=2.9.10` - PostgreSQL适配器
- `SQLAlchemy>=2.0.0` - 数据库ORM
- `Flask>=3.0.2` - Web框架（用于配置管理）

### 数据库连接
- **PostgreSQL**: 需要访问 `dataops` 数据库的 `hotel_positions` 和 `hotel_group_brands` 表
- **Neo4j**: 需要访问Neo4j图数据库

### 配置要求
程序会自动读取 `app/config/config.py` 中的数据库连接配置：

```python
# PostgreSQL配置
SQLALCHEMY_DATABASE_URI = 'postgresql://username:password@host:port/database'

# Neo4j配置
NEO4J_URI = "bolt://host:port"
NEO4J_USER = "username"
NEO4J_PASSWORD = "password"
NEO4J_ENCRYPTED = False
```

## 输出说明

### 控制台输出
程序会在控制台显示执行进度和结果：
```
2024-01-01 10:00:00 - INFO - 开始执行酒店职位数据和酒店集团品牌数据Neo4j同步程序
2024-01-01 10:00:01 - INFO - PostgreSQL数据库连接成功
2024-01-01 10:00:02 - INFO - Neo4j数据库连接成功
2024-01-01 10:00:03 - INFO - 开始处理酒店职位数据...
2024-01-01 10:00:04 - INFO - 成功获取 15 条酒店职位数据
2024-01-01 10:00:05 - INFO - 成功创建部门节点: 前厅部
2024-01-01 10:00:06 - INFO - 成功创建职位节点: 前台接待
2024-01-01 10:00:07 - INFO - 成功创建级别节点: 初级
2024-01-01 10:00:08 - INFO - 成功创建关系: 前台接待 BELONGS_TO 前厅部
2024-01-01 10:00:09 - INFO - 成功创建关系: 前台接待 HAS_LEVEL 初级
...
2024-01-01 10:00:15 - INFO - 酒店职位数据同步完成: 酒店职位数据同步完成
2024-01-01 10:00:15 - INFO - 总计记录: 15
2024-01-01 10:00:15 - INFO - 部门节点 - 新建: 8, 跳过: 2
2024-01-01 10:00:15 - INFO - 职位节点 - 新建: 12, 跳过: 3
2024-01-01 10:00:15 - INFO - 级别节点 - 新建: 5, 跳过: 1
2024-01-01 10:00:15 - INFO - 关系创建: 30
2024-01-01 10:00:16 - INFO - 开始处理酒店集团品牌数据...
2024-01-01 10:00:17 - INFO - 成功获取 20 条酒店集团品牌数据
2024-01-01 10:00:18 - INFO - 成功创建集团节点: 万豪国际
2024-01-01 10:00:19 - INFO - 成功创建品牌节点: 丽思卡尔顿
2024-01-01 10:00:20 - INFO - 成功创建品牌级别节点: 奢华
2024-01-01 10:00:21 - INFO - 成功创建关系: 丽思卡尔顿 BELONGS_TO 万豪国际
2024-01-01 10:00:22 - INFO - 成功创建关系: 丽思卡尔顿 HAS_LEVEL 奢华
...
2024-01-01 10:00:30 - INFO - 酒店集团品牌数据同步完成: 酒店集团品牌数据同步完成
2024-01-01 10:00:30 - INFO - 总计记录: 20
2024-01-01 10:00:30 - INFO - 集团节点 - 新建: 12, 跳过: 3
2024-01-01 10:00:30 - INFO - 品牌节点 - 新建: 18, 跳过: 2
2024-01-01 10:00:30 - INFO - 品牌级别节点 - 新建: 8, 跳过: 1
2024-01-01 10:00:30 - INFO - 关系创建: 40
2024-01-01 10:00:30 - INFO - 所有数据同步任务完成
```

### 日志文件
程序会在 `logs/parse_neo4j_process.log` 文件中记录详细的执行日志。

### 返回结果
程序返回执行结果统计，包括两个数据表的处理结果：

#### 酒店职位数据结果
```python
{
    'success': True,
    'message': '酒店职位数据同步完成',
    'total': 15,                    # 总记录数
    'departments_created': 8,       # 新建部门节点数
    'departments_skipped': 2,       # 跳过部门节点数
    'positions_created': 12,        # 新建职位节点数
    'positions_skipped': 3,         # 跳过职位节点数
    'levels_created': 5,            # 新建级别节点数
    'levels_skipped': 1,            # 跳过级别节点数
    'relationships_created': 30     # 创建关系数
}
```

#### 酒店集团品牌数据结果
```python
{
    'success': True,
    'message': '酒店集团品牌数据同步完成',
    'total': 20,                    # 总记录数
    'groups_created': 12,           # 新建集团节点数
    'groups_skipped': 3,            # 跳过集团节点数
    'brands_created': 18,           # 新建品牌节点数
    'brands_skipped': 2,            # 跳过品牌节点数
    'brand_levels_created': 8,      # 新建品牌级别节点数
    'brand_levels_skipped': 1,      # 跳过品牌级别节点数
    'relationships_created': 40     # 创建关系数
}
```

## 图数据库结构

### 节点类型
程序会创建六种类型的DataLabel节点：

#### 酒店职位相关节点
1. **部门节点** (`node_type: 'department'`)
2. **职位节点** (`node_type: 'position'`)
3. **职位级别节点** (`node_type: 'position_level'`)

#### 酒店集团品牌相关节点
4. **集团节点** (`node_type: 'group'`)
5. **品牌节点** (`node_type: 'brand'`)
6. **品牌级别节点** (`node_type: 'brand_level'`)

### 关系类型

#### 酒店职位关系
1. **BELONGS_TO**: 职位 → 部门
   - 表示职位属于某个部门
   - 例如：前台接待 BELONGS_TO 前厅部

2. **HAS_LEVEL**: 职位 → 级别
   - 表示职位具有某个级别
   - 例如：前台接待 HAS_LEVEL 初级

#### 酒店集团品牌关系
3. **BELONGS_TO**: 品牌 → 集团
   - 表示品牌属于某个集团
   - 例如：丽思卡尔顿 BELONGS_TO 万豪国际

4. **HAS_LEVEL**: 品牌 → 品牌级别
   - 表示品牌具有某个定位级别
   - 例如：丽思卡尔顿 HAS_LEVEL 奢华

### 图结构示例

#### 酒店职位结构
```
(前厅部:DataLabel {name: '前厅部', node_type: 'department'})
    ↑ BELONGS_TO
(前台接待:DataLabel {name: '前台接待', node_type: 'position'})
    ↓ HAS_LEVEL
(初级:DataLabel {name: '初级', node_type: 'position_level'})
```

#### 酒店集团品牌结构
```
(万豪国际:DataLabel {name: '万豪国际', node_type: 'group'})
    ↑ BELONGS_TO
(丽思卡尔顿:DataLabel {name: '丽思卡尔顿', node_type: 'brand'})
    ↓ HAS_LEVEL
(奢华:DataLabel {name: '奢华', node_type: 'brand_level'})
```

## 错误处理

### 常见错误及解决方案

1. **数据库连接失败**
   - 检查数据库服务是否启动
   - 验证连接字符串和认证信息
   - 确认网络连接和防火墙设置

2. **表不存在或权限不足**
   - 确认 `hotel_positions` 和 `hotel_group_brands` 表存在
   - 检查数据库用户权限
   - 验证表结构是否符合预期

3. **Neo4j节点创建失败**
   - 检查Neo4j服务状态
   - 验证用户权限
   - 确认Cypher查询语法正确

4. **关系创建失败**
   - 确认相关节点已存在
   - 检查Neo4j权限设置
   - 验证关系类型是否支持

### 错误日志
所有错误都会记录在日志文件中，包括：
- 错误类型和描述
- 错误发生的具体位置
- 完整的错误堆栈信息

## 性能优化

### 批量处理
- 程序分别批量处理两个数据表，避免混合查询
- 使用事务确保数据一致性
- 关系创建使用MERGE操作，避免重复

### 资源管理
- 自动管理数据库连接池
- 及时释放Neo4j会话资源
- 程序结束时自动清理所有资源

## 扩展功能

### 自定义配置
可以通过修改配置类来调整程序行为：
- 数据库连接参数
- 日志级别和格式
- 批处理大小

### 数据过滤
可以修改SQL查询来添加更多过滤条件：
- 按时间范围过滤
- 按状态过滤
- 按类型过滤

### 节点属性扩展
可以轻松添加更多节点属性：
- 描述信息
- 创建者信息
- 标签分类
- 自定义元数据

### 关系扩展
可以添加更多关系类型：
- 职位之间的上下级关系
- 部门之间的从属关系
- 级别之间的层次关系
- 集团之间的合作关系

## 注意事项

1. **数据一致性**: 程序使用事务确保数据一致性，如果中途失败会自动回滚
2. **重复执行**: 程序可以安全地重复执行，不会产生重复数据
3. **资源占用**: 程序会占用数据库连接，建议在低峰期执行
4. **备份建议**: 执行前建议备份Neo4j数据库
5. **关系创建**: 关系创建依赖于节点存在，确保节点创建成功后再创建关系
6. **数据完整性**: 确保两个数据表的数据完整性和一致性

## 技术支持

如果遇到问题，请检查：
1. 日志文件中的错误信息
2. 数据库连接配置
3. 网络连接状态
4. 数据库服务状态
5. Neo4j图数据库权限设置
6. 数据表结构和数据质量

## 版本历史

- v1.0.0: 初始版本，支持基本的酒店职位数据同步功能
- v1.1.0: 增强版本，支持职位名称、级别名称同步和节点关系创建
- v1.2.0: 扩展版本，新增酒店集团品牌数据同步功能，支持完整的酒店数据生态 