文件删除时同步删除ElasticSearch索引的PHP代码问题求助
问题分析与解决方案
核心问题
你的代码存在三个关键问题:
- 文件不存在时调用
md5_file()会触发PHP警告,且返回false,导致$md5值完全无效,无法传入ES执行删除操作 - 判断逻辑完全颠倒:
empty(md5_file($path))在文件存在时,MD5哈希非空,empty()返回false,不会执行删除;文件不存在时返回true,但此时$md5是false,传去ES删除毫无意义 - 最根本的矛盾:文件已经被删除,无法通过
md5_file()获取它曾经的MD5值,而ES删除必须依赖这个MD5作为文档ID
解决思路
要实现文件删除后同步删除ES索引,必须提前记录文件与对应MD5的映射关系——比如用本地JSON文件、数据库存储。当检测到文件不存在时,从存储中取出该文件对应的MD5,再执行ES删除操作。
修正后的代码示例
以下是基于本地JSON文件存储映射关系的实现:
<?php // 定义目标文件路径和映射存储文件 $filePath = __DIR__ . "/uploads/Арне.pptx"; $filename = basename($filePath); $mappingFile = __DIR__ . "/file_mappings.json"; // 读取已有的文件-MD5映射记录 $mappings = []; if (file_exists($mappingFile)) { $mappings = json_decode(file_get_contents($mappingFile), true) ?: []; } // 检测文件是否存在 if (!file_exists($filePath)) { // 文件不存在,从映射中查找对应MD5 if (isset($mappings[$filename])) { $targetMd5 = $mappings[$filename]; // 执行ES删除操作 $params = [ 'index' => 'bower', 'id' => $targetMd5 ]; $response = $client->delete($params); // 删除成功后,移除映射中的记录 unset($mappings[$filename]); file_put_contents($mappingFile, json_encode($mappings, JSON_PRETTY_PRINT)); echo "已删除ES中对应文件的索引"; } else { echo "未找到该文件的MD5映射记录"; } } else { // 文件存在,生成MD5并更新映射(适配新文件或文件内容变更的情况) $currentMd5 = md5_file($filePath); if (!isset($mappings[$filename]) || $mappings[$filename] !== $currentMd5) { $mappings[$filename] = $currentMd5; file_put_contents($mappingFile, json_encode($mappings, JSON_PRETTY_PRINT)); } echo "文件存在,已更新MD5映射"; }
补充方案
如果你的ES索引中已经存储了filename字段,也可以通过文件名查询获取对应的文档ID(MD5),再执行删除:
// 文件不存在时,通过文件名查询ES文档 $params = [ 'index' => 'bower', 'body' => [ 'query' => [ 'match' => [ 'filename' => $filename ] ] ] ]; $searchResponse = $client->search($params); if (!empty($searchResponse['hits']['hits'])) { $docId = $searchResponse['hits']['hits'][0]['_id']; // 执行删除 $deleteParams = [ 'index' => 'bower', 'id' => $docId ]; $client->delete($deleteParams); }
注意:实际使用时建议添加try-catch块捕获ES客户端的异常(比如网络错误、文档不存在等),避免脚本崩溃。
内容的提问来源于stack exchange,提问作者SplendX
相关产品推荐
相关产品推荐

