|
| 1 | +# Elasticsearch 数据库查询工具 |
| 2 | + |
| 3 | +一个强大的 Elasticsearch 8.x 只读查询工具,支持执行各种 ES 查询操作,为 MaxKB 智能体平台提供 Elasticsearch 查询能力。 |
| 4 | + |
| 5 | +## 功能特性 |
| 6 | + |
| 7 | +- ✅ 支持 Elasticsearch 8.x 版本 |
| 8 | +- ✅ 支持文档搜索、聚合分析、集群信息查询 |
| 9 | +- ✅ 集成到 MaxKB 智能体平台 |
| 10 | +- ✅ 简单易用的配置和部署 |
| 11 | +- ✅ 支持灵活的查询 DSL |
| 12 | +- ✅ 支持多索引搜索和批量文档获取 |
| 13 | +- ✅ 安全的白名单验证机制 |
| 14 | +- ✅ 支持 HTTPS 连接和 SSL 证书验证 |
| 15 | +- ✅ 友好的中文错误提示 |
| 16 | + |
| 17 | +## 系统要求 |
| 18 | + |
| 19 | +- Elasticsearch 8.x 集群 |
| 20 | +- MaxKB 平台环境 |
| 21 | +- Python 3.7+ |
| 22 | + |
| 23 | +## 安装依赖 |
| 24 | + |
| 25 | +在使用此工具之前,需要先安装所需的依赖包: |
| 26 | + |
| 27 | +```bash |
| 28 | +pip install elasticsearch>=8.0.0,<9.0.0 |
| 29 | +``` |
| 30 | + |
| 31 | +依赖包说明: |
| 32 | +- `elasticsearch>=8.0.0,<9.0.0` - Elasticsearch Python 客户端(8.x 版本) |
| 33 | + |
| 34 | +## 参数说明 |
| 35 | + |
| 36 | +| 参数 | 类型 | 必填 | 默认值 | 说明 | |
| 37 | +|------|------|------|--------|------| |
| 38 | +| host | string | 是 | - | Elasticsearch 服务器地址 | |
| 39 | +| port | string | 是 | 9200 | Elasticsearch 端口 | |
| 40 | +| user | string | 是 | - | 认证用户名 | |
| 41 | +| password | string | 是 | - | 认证密码 | |
| 42 | +| use_ssl | boolean | 否 | true | 是否使用 HTTPS 连接 | |
| 43 | +| verify_certs | boolean | 否 | true | 是否验证 SSL 证书 | |
| 44 | +| api_path | string | 是 | - | ES API 路径(如: index_name/_search) | |
| 45 | +| query_dsl | string | 否 | - | 查询 DSL JSON 字符串(可选) | |
| 46 | +| timeout | number | 否 | 30 | 连接超时时间(秒) | |
| 47 | + |
| 48 | +## 支持的 API |
| 49 | + |
| 50 | +### 搜索类 API |
| 51 | +- `_search` - 搜索文档 |
| 52 | +- `_mget` - 批量获取多个文档 |
| 53 | +- `_count` - 统计文档数量 |
| 54 | +- `_validate/query` - 验证查询语法 |
| 55 | + |
| 56 | +### 信息类 API |
| 57 | +- `_get` 或 `_doc/{id}` - 获取单个文档 |
| 58 | +- `_cat/*` - 集群信息查询(indices, aliases, health, nodes 等) |
| 59 | +- `_cluster/health` - 集群健康状态 |
| 60 | +- `_cluster/state` - 集群状态 |
| 61 | +- `_aliases` - 索引别名信息 |
| 62 | +- `_mapping` - 索引映射信息 |
| 63 | +- `_settings` - 索引设置 |
| 64 | + |
| 65 | +## 使用示例 |
| 66 | + |
| 67 | +### 基础搜索 |
| 68 | + |
| 69 | +```python |
| 70 | +# 搜索所有文档 |
| 71 | +result = query_elasticsearch( |
| 72 | + host="localhost", |
| 73 | + port="9200", |
| 74 | + user="elastic", |
| 75 | + password="changeme", |
| 76 | + api_path="my_index/_search", |
| 77 | + query_dsl='{"query": {"match_all": {}}}' |
| 78 | +) |
| 79 | + |
| 80 | +# 条件搜索 |
| 81 | +result = query_elasticsearch( |
| 82 | + host="localhost", |
| 83 | + port="9200", |
| 84 | + user="elastic", |
| 85 | + password="changeme", |
| 86 | + api_path="my_index/_search", |
| 87 | + query_dsl='{"query": {"match": {"title": "搜索关键词"}}}' |
| 88 | +) |
| 89 | +``` |
| 90 | + |
| 91 | +### 获取单个文档 |
| 92 | + |
| 93 | +```python |
| 94 | +result = query_elasticsearch( |
| 95 | + host="localhost", |
| 96 | + port="9200", |
| 97 | + user="elastic", |
| 98 | + password="changeme", |
| 99 | + api_path="my_index/_doc/123" |
| 100 | +) |
| 101 | +``` |
| 102 | + |
| 103 | +### 批量获取多个文档 |
| 104 | + |
| 105 | +```python |
| 106 | +result = query_elasticsearch( |
| 107 | + host="localhost", |
| 108 | + port="9200", |
| 109 | + user="elastic", |
| 110 | + password="changeme", |
| 111 | + api_path="_mget", |
| 112 | + query_dsl='{"docs": [{"_index": "my_index", "_id": "1"}, {"_index": "my_index", "_id": "2"}]}' |
| 113 | +) |
| 114 | +``` |
| 115 | + |
| 116 | +### 多索引搜索 |
| 117 | + |
| 118 | +```python |
| 119 | +result = query_elasticsearch( |
| 120 | + host="localhost", |
| 121 | + port="9200", |
| 122 | + user="elastic", |
| 123 | + password="changeme", |
| 124 | + api_path="index1,index2/_search", |
| 125 | + query_dsl='{"query": {"match_all": {}}}' |
| 126 | +) |
| 127 | +``` |
| 128 | + |
| 129 | +### 聚合查询 |
| 130 | + |
| 131 | +```python |
| 132 | +result = query_elasticsearch( |
| 133 | + host="localhost", |
| 134 | + port="9200", |
| 135 | + user="elastic", |
| 136 | + password="changeme", |
| 137 | + api_path="my_index/_search", |
| 138 | + query_dsl='{"size": 0, "aggs": {"avg_price": {"avg": {"field": "price"}}}}' |
| 139 | +) |
| 140 | +``` |
| 141 | + |
| 142 | +### 集群信息查询 |
| 143 | + |
| 144 | +```python |
| 145 | +# 集群健康状态 |
| 146 | +result = query_elasticsearch( |
| 147 | + host="localhost", |
| 148 | + port="9200", |
| 149 | + user="elastic", |
| 150 | + password="changeme", |
| 151 | + api_path="_cluster/health" |
| 152 | +) |
| 153 | + |
| 154 | +# 索引列表 |
| 155 | +result = query_elasticsearch( |
| 156 | + host="localhost", |
| 157 | + port="9200", |
| 158 | + user="elastic", |
| 159 | + password="changeme", |
| 160 | + api_path="_cat/indices" |
| 161 | +) |
| 162 | + |
| 163 | +# 索引映射 |
| 164 | +result = query_elasticsearch( |
| 165 | + host="localhost", |
| 166 | + port="9200", |
| 167 | + user="elastic", |
| 168 | + password="changeme", |
| 169 | + api_path="my_index/_mapping" |
| 170 | +) |
| 171 | +``` |
| 172 | + |
| 173 | +## 错误处理 |
| 174 | + |
| 175 | +工具会返回友好的中文错误提示: |
| 176 | + |
| 177 | +| 错误类型 | 提示信息 | |
| 178 | +|----------|----------| |
| 179 | +| 连接失败 | 无法连接到 Elasticsearch 服务器 {host}:{port},请检查地址和端口 | |
| 180 | +| 认证失败 | 认证失败,请检查用户名和密码 | |
| 181 | +| SSL 错误 | SSL 证书验证失败,请检查证书或设置 verify_certs=False | |
| 182 | +| 权限不足 | 权限不足,请检查用户是否有相应的查询权限 | |
| 183 | +| 索引不存在 | 索引 {index_name} 不存在 | |
| 184 | +| 查询语法错误 | 查询语法错误: {详细信息} | |
| 185 | +| 超时 | 连接超时,请检查网络或增加 timeout 参数 | |
| 186 | +| 不支持的 API | 不允许的 API 路径: {api_path}。此工具只支持只读查询操作 | |
| 187 | +| 不支持的 HTTP 方法 | 不支持的 HTTP 方法: {method}。只允许 GET 和 HEAD 请求 | |
| 188 | + |
| 189 | +## 安全验证 |
| 190 | + |
| 191 | +工具实现了双重安全验证机制: |
| 192 | + |
| 193 | +1. **白名单路径验证**: 只允许预定义的只读 API 路径 |
| 194 | +2. **HTTP 方法验证**: 只允许 GET 和 HEAD 请求 |
| 195 | + |
| 196 | +这确保了工具只能执行只读查询操作,防止误操作导致数据修改或删除。 |
| 197 | + |
| 198 | +## 注意事项 |
| 199 | + |
| 200 | +1. 生产环境建议使用专用只读账户 |
| 201 | +2. 建议在 ES 集群配置中启用安全认证和 HTTPS |
| 202 | +3. 不要在日志中记录敏感信息(如密码) |
| 203 | +4. 检查防火墙是否允许 ES 端口访问 |
| 204 | +5. 大数据量查询时建议在 query_dsl 中添加分页参数(from, size) |
| 205 | +6. 避免使用高开销的查询(如通配符查询、正则查询)在大数据集上 |
| 206 | +7. 建议设置合理的 timeout 参数,避免长时间等待 |
| 207 | + |
| 208 | +## 测试说明 |
| 209 | + |
| 210 | +### 本地测试 |
| 211 | + |
| 212 | +在提交工具前,建议进行以下测试: |
| 213 | + |
| 214 | +1. **参数验证测试** |
| 215 | +```python |
| 216 | +from elasticsearch_query import query_elasticsearch |
| 217 | + |
| 218 | +# 测试缺少必填参数 |
| 219 | +result = query_elasticsearch(host="", port="9200", user="elastic", password="changeme", api_path="test/_search") |
| 220 | +print(result) # 应返回参数错误 |
| 221 | + |
| 222 | +# 测试无效的 API 路径 |
| 223 | +result = query_elasticsearch(host="localhost", port="9200", user="elastic", password="changeme", api_path="test/_delete") |
| 224 | +print(result) # 应返回不允许的 API 路径错误 |
| 225 | +``` |
| 226 | + |
| 227 | +2. **连接测试** |
| 228 | +```python |
| 229 | +# 测试基础搜索(需要实际 ES 环境) |
| 230 | +result = query_elasticsearch( |
| 231 | + host="localhost", |
| 232 | + port="9200", |
| 233 | + user="elastic", |
| 234 | + password="changeme", |
| 235 | + api_path="_cat/indices" |
| 236 | +) |
| 237 | +print(result) # 应返回索引列表或认证失败错误 |
| 238 | +``` |
| 239 | + |
| 240 | +3. **查询 DSL 测试** |
| 241 | +```python |
| 242 | +# 测试无效的 JSON |
| 243 | +result = query_elasticsearch( |
| 244 | + host="localhost", |
| 245 | + port="9200", |
| 246 | + user="elastic", |
| 247 | + password="changeme", |
| 248 | + api_path="test_index/_search", |
| 249 | + query_dsl="{invalid json}" |
| 250 | +) |
| 251 | +print(result) # 应返回 JSON 解析错误 |
| 252 | +``` |
| 253 | + |
| 254 | +### 集成测试 |
| 255 | + |
| 256 | +在 MaxKB 平台中测试: |
| 257 | + |
| 258 | +1. 上传工具到平台 |
| 259 | +2. 配置连接参数 |
| 260 | +3. 测试各种 API 路径: |
| 261 | + - `_cat/indices` - 获取索引列表 |
| 262 | + - `index_name/_search` - 搜索文档 |
| 263 | + - `_cluster/health` - 集群健康状态 |
| 264 | +4. 验证错误处理是否返回友好的中文提示 |
0 commit comments