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

## 快速开始

### 1. 环境准备

确保您的环境满足以下要求：
- Python 3.7+
- PostgreSQL数据库（包含hotel_positions和hotel_group_brands表）
- Neo4j图数据库
- 必要的Python依赖包

### 2. 配置检查

确认 `app/config/config.py` 中的数据库配置正确：

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

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

### 3. 运行程序

#### 方法1：直接运行Python脚本
```bash
# 在项目根目录下运行
python app/core/data_parse/parse_neo4j_process.py
```

#### 方法2：使用批处理文件（Windows）
```bash
# 双击运行
run_parse_neo4j.bat

# 或在命令行中运行
.\run_parse_neo4j.bat
```

#### 方法3：使用Shell脚本（Linux/Mac）
```bash
# 添加执行权限（首次运行）
chmod +x run_parse_neo4j.sh

# 运行脚本
./run_parse_neo4j.sh
```

## 使用示例

### 基本使用

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

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

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

if success:
    print("所有数据同步成功！")
else:
    print("部分或全部数据同步失败！")
```

### 自定义处理

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

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

# 连接数据库
if processor.connect_postgresql() and processor.connect_neo4j():
    
    # 处理酒店职位数据
    print("开始处理酒店职位数据...")
    positions_result = processor.process_hotel_positions()
    
    if positions_result['success']:
        print(f"酒店职位数据同步完成！")
        print(f"部门节点: 新建 {positions_result['departments_created']}, 跳过 {positions_result['departments_skipped']}")
        print(f"职位节点: 新建 {positions_result['positions_created']}, 跳过 {positions_result['positions_skipped']}")
        print(f"级别节点: 新建 {positions_result['levels_created']}, 跳过 {positions_result['levels_skipped']}")
        print(f"关系创建: {positions_result['relationships_created']}")
    else:
        print(f"酒店职位数据同步失败: {positions_result['message']}")
    
    # 处理酒店集团品牌数据
    print("\n开始处理酒店集团品牌数据...")
    brands_result = processor.process_hotel_group_brands()
    
    if brands_result['success']:
        print(f"酒店集团品牌数据同步完成！")
        print(f"集团节点: 新建 {brands_result['groups_created']}, 跳过 {brands_result['groups_skipped']}")
        print(f"品牌节点: 新建 {brands_result['brands_created']}, 跳过 {brands_result['brands_skipped']}")
        print(f"品牌级别节点: 新建 {brands_result['brand_levels_created']}, 跳过 {brands_result['brand_levels_skipped']}")
        print(f"关系创建: {brands_result['relationships_created']}")
    else:
        print(f"酒店集团品牌数据同步失败: {brands_result['message']}")
```

### 分别获取数据

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

processor = HotelPositionNeo4jProcessor()

if processor.connect_postgresql():
    # 获取酒店职位数据
    positions = processor.get_hotel_positions()
    print(f"获取到 {len(positions)} 条酒店职位数据")
    
    # 获取酒店集团品牌数据
    brands = processor.get_hotel_group_brands()
    print(f"获取到 {len(brands)} 条酒店集团品牌数据")
    
    # 显示数据示例
    if positions:
        print("\n酒店职位数据示例:")
        for i, pos in enumerate(positions[:3]):
            print(f"  {i+1}. {pos['department_zh']} - {pos['position_zh']} - {pos['level_zh']}")
    
    if brands:
        print("\n酒店集团品牌数据示例:")
        for i, brand in enumerate(brands[:3]):
            print(f"  {i+1}. {brand['group_name_zh']} - {brand['brand_name_zh']} - {brand['positioning_level_zh']}")
```

## 输出示例

### 成功执行示例

```
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:10 - INFO - 部门节点已存在，跳过: 客房部
2024-01-01 10:00:11 - INFO - 成功创建职位节点: 客房服务员
2024-01-01 10:00:12 - INFO - 级别节点已存在，跳过: 初级
2024-01-01 10:00:13 - INFO - 成功创建关系: 客房服务员 BELONGS_TO 客房部
2024-01-01 10:00:14 - INFO - 成功创建关系: 客房服务员 HAS_LEVEL 初级
...
2024-01-01 10:00:20 - INFO - 酒店职位数据同步完成: 酒店职位数据同步完成
2024-01-01 10:00:20 - INFO - 总计记录: 15
2024-01-01 10:00:20 - INFO - 部门节点 - 新建: 8, 跳过: 2
2024-01-01 10:00:20 - INFO - 职位节点 - 新建: 12, 跳过: 3
2024-01-01 10:00:20 - INFO - 级别节点 - 新建: 5, 跳过: 1
2024-01-01 10:00:20 - INFO - 关系创建: 30
2024-01-01 10:00:21 - INFO - 开始处理酒店集团品牌数据...
2024-01-01 10:00:22 - INFO - 成功获取 20 条酒店集团品牌数据
2024-01-01 10:00:23 - INFO - 成功创建集团节点: 万豪国际
2024-01-01 10:00:24 - INFO - 成功创建品牌节点: 丽思卡尔顿
2024-01-01 10:00:25 - INFO - 成功创建品牌级别节点: 奢华
2024-01-01 10:00:26 - INFO - 成功创建关系: 丽思卡尔顿 BELONGS_TO 万豪国际
2024-01-01 10:00:27 - INFO - 成功创建关系: 丽思卡尔顿 HAS_LEVEL 奢华
2024-01-01 10:00:28 - INFO - 集团节点已存在，跳过: 希尔顿
2024-01-01 10:00:29 - INFO - 成功创建品牌节点: 华尔道夫
2024-01-01 10:00:30 - INFO - 品牌级别节点已存在，跳过: 奢华
2024-01-01 10:00:31 - INFO - 成功创建关系: 华尔道夫 BELONGS_TO 希尔顿
2024-01-01 10:00:32 - INFO - 成功创建关系: 华尔道夫 HAS_LEVEL 奢华
...
2024-01-01 10:00:40 - INFO - 酒店集团品牌数据同步完成: 酒店集团品牌数据同步完成
2024-01-01 10:00:40 - INFO - 总计记录: 20
2024-01-01 10:00:40 - INFO - 集团节点 - 新建: 12, 跳过: 3
2024-01-01 10:00:40 - INFO - 品牌节点 - 新建: 18, 跳过: 2
2024-01-01 10:00:40 - INFO - 品牌级别节点 - 新建: 8, 跳过: 1
2024-01-01 10:00:40 - INFO - 关系创建: 40
2024-01-01 10:00:40 - INFO - 所有数据同步任务完成
2024-01-01 10:00:40 - INFO - 程序执行完成，资源已清理
```

### 错误处理示例

```
2024-01-01 10:00:00 - INFO - 开始执行酒店职位数据和酒店集团品牌数据Neo4j同步程序
2024-01-01 10:00:01 - ERROR - PostgreSQL数据库连接失败: (psycopg2.OperationalError) connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
2024-01-01 10:00:01 - ERROR - 无法连接PostgreSQL数据库，程序退出
2024-01-01 10:00:01 - INFO - 程序执行完成，资源已清理
```

## 数据验证

### 在Neo4j中查看结果

运行程序后，您可以在Neo4j浏览器中执行以下查询来验证结果：

#### 查看所有节点
```cypher
MATCH (n:DataLabel) RETURN n LIMIT 20
```

#### 查看酒店职位相关节点
```cypher
// 查看部门节点
MATCH (n:DataLabel {node_type: 'department'}) RETURN n

// 查看职位节点
MATCH (n:DataLabel {node_type: 'position'}) RETURN n

// 查看职位级别节点
MATCH (n:DataLabel {node_type: 'position_level'}) RETURN n
```

#### 查看酒店集团品牌相关节点
```cypher
// 查看集团节点
MATCH (n:DataLabel {node_type: 'group'}) RETURN n

// 查看品牌节点
MATCH (n:DataLabel {node_type: 'brand'}) RETURN n

// 查看品牌级别节点
MATCH (n:DataLabel {node_type: 'brand_level'}) RETURN n
```

#### 查看关系
```cypher
MATCH (from:DataLabel)-[r]->(to:DataLabel) 
RETURN from.name, type(r), to.name
```

#### 查看完整的酒店职位结构
```cypher
MATCH (dept:DataLabel {node_type: 'department'})
MATCH (pos:DataLabel {node_type: 'position'})
MATCH (level:DataLabel {node_type: 'position_level'})
MATCH (pos)-[:BELONGS_TO]->(dept)
MATCH (pos)-[:HAS_LEVEL]->(level)
RETURN dept.name as 部门, pos.name as 职位, level.name as 级别
ORDER BY dept.name, pos.name
```

#### 查看完整的酒店集团品牌结构
```cypher
MATCH (group:DataLabel {node_type: 'group'})
MATCH (brand:DataLabel {node_type: 'brand'})
MATCH (level:DataLabel {node_type: 'brand_level'})
MATCH (brand)-[:BELONGS_TO]->(group)
MATCH (brand)-[:HAS_LEVEL]->(level)
RETURN group.name as 集团, brand.name as 品牌, level.name as 级别
ORDER BY group.name, brand.name
```

#### 查看所有节点类型统计
```cypher
MATCH (n:DataLabel)
RETURN n.node_type as 节点类型, count(n) as 数量
ORDER BY 数量 DESC
```

#### 查看关系类型统计
```cypher
MATCH ()-[r]->()
RETURN type(r) as 关系类型, count(r) as 数量
ORDER BY 数量 DESC
```

## 常见问题

### Q: 程序运行时提示"模块导入失败"
A: 确保您在项目根目录下运行程序，或者将项目根目录添加到Python路径中。

### Q: 数据库连接失败
A: 检查数据库服务是否启动，连接字符串是否正确，网络连接是否正常。

### Q: 表不存在或权限不足
A: 确认 `hotel_positions` 和 `hotel_group_brands` 表存在，检查数据库用户权限。

### Q: Neo4j节点创建失败
A: 检查Neo4j服务状态，验证用户权限，确认Cypher查询语法正确。

### Q: 关系创建失败
A: 确保相关节点已存在，检查Neo4j权限设置。

### Q: 如何重复运行程序
A: 程序可以安全地重复运行，会自动跳过已存在的节点，只创建新的节点和关系。

### Q: 如何处理部分数据同步失败
A: 程序会分别处理两个数据表，即使其中一个失败，另一个仍会继续执行。检查日志了解具体失败原因。

## 性能优化建议

1. **批量处理**: 程序已优化为批量处理，避免多次数据库查询
2. **事务管理**: 使用事务确保数据一致性
3. **资源管理**: 自动管理数据库连接和会话资源
4. **去重逻辑**: 避免重复创建节点和关系
5. **并行处理**: 可以考虑将两个数据表的处理改为并行执行（需要进一步优化）

## 监控和日志

- 程序会在控制台显示实时进度
- 详细日志保存在 `logs/parse_neo4j_process.log` 文件中
- 可以通过日志文件排查问题和监控执行情况
- 支持分别监控两个数据表的处理进度

## 扩展建议

1. **定时任务**: 可以设置为定时任务，定期同步数据
2. **增量同步**: 可以扩展为只同步新增或修改的数据
3. **数据验证**: 可以添加数据质量检查和验证功能
4. **性能监控**: 可以添加执行时间统计和性能指标
5. **并行处理**: 可以优化为并行处理两个数据表，提高执行效率
6. **数据一致性检查**: 可以添加数据一致性验证功能 