如何通过ID检索Zend Lucene中已索引文档的内容
如何通过ID检索Zend Lucene中已索引文档的内容
嘿,我来帮你搞定这个问题!你当前的索引代码里有两个关键设置问题,导致没法通过ID检索到文档内容,我给你一步步梳理清楚:
先说说你现有代码的问题
- 你把
Id字段设成了UnIndexed类型,这个类型的字段不会被加入搜索索引库,所以Lucene根本没法用这个字段来做查询匹配; - 另外
contents用了UnStored类型,这个类型的字段只会被用来分词构建索引(满足关键词搜索需求),但不会把原始内容存储在索引里——哪怕你侥幸找到对应的文档,也没法从索引里直接取出内容。
修改后的索引代码
首先得调整字段的类型设置,确保ID能被搜索、内容能被存储(或者你可以选择只存文件路径,后面说这个更省空间的方案):
$doc = new \Zend_Search_Lucene_Document(); // 把Id设为Keyword类型:适合ID这种唯一标识,不分词、可搜索、会存储 $doc->addField(\Zend_Search_Lucene_Field::Keyword('Id', (integer)$args['resId'])); // 把contents设为Text类型:既会分词索引(满足关键词搜索),又会存储原始内容 $doc->addField(\Zend_Search_Lucene_Field::Text('contents', $fileContent, 'utf-8')); $index->addDocument($doc); $index->commit(); // 别忘了提交索引的更改,不然新索引的内容不会生效
通过ID检索内容的代码
现在就可以用ID来精准查询对应的文档,再取出内容了:
// 先打开你的索引库 $index = \Zend_Search_Lucene::open('/path/to/your/index/directory'); // 替换成你要查询的目标ID $targetId = 123; // 创建针对Id字段的精确匹配查询 $query = new \Zend_Search_Lucene_Search_Query_Term( new \Zend_Search_Lucene_Index_Term($targetId, 'Id') ); // 执行查询 $searchResults = $index->find($query); // 处理查询结果 if (!empty($searchResults)) { // 因为ID是唯一标识,所以直接取第一个结果即可 $targetDocument = $searchResults[0]; // 取出存储的文档内容 $fileContents = $targetDocument->contents; // 这里就可以用你拿到的内容做后续操作了 var_dump($fileContents); } else { echo "没有找到对应ID的文档哦"; }
更节省索引空间的替代方案
如果你的文档内容很大,直接存在索引里会让索引体积暴增,那可以换个思路:索引的时候只存Id和文件的本地路径,通过ID找到路径后,再去读取本地文件的内容:
调整后的索引代码
$doc = new \Zend_Search_Lucene_Document(); $doc->addField(\Zend_Search_Lucene_Field::Keyword('Id', (integer)$args['resId'])); // 新增存储文件路径的字段 $doc->addField(\Zend_Search_Lucene_Field::Keyword('file_path', $yourFileLocalPath)); // contents还是用UnStored,满足关键词搜索但不存原始内容 $doc->addField(\Zend_Search_Lucene_Field::UnStored('contents', $fileContent, 'utf-8')); $index->addDocument($doc); $index->commit();
对应的查询代码
$index = \Zend_Search_Lucene::open('/path/to/your/index/directory'); $targetId = 123; $query = new \Zend_Search_Lucene_Search_Query_Term( new \Zend_Search_Lucene_Index_Term($targetId, 'Id') ); $searchResults = $index->find($query); if (!empty($searchResults)) { $targetDocument = $searchResults[0]; // 取出文件路径,再读取本地文件内容 $filePath = $targetDocument->file_path; $fileContents = file_get_contents($filePath); var_dump($fileContents); } else { echo "未找到对应ID的文档"; }
备注:内容来源于stack exchange,提问作者Nathan30




