在更新索引中的文档创建 IndexWriter 实例时出现下面的错误,请问如何解决?
System.IO.FileNotFoundException: Could not find file '/zzk/index/blogpost/_1bx.fnm'.
File name: '/zzk/index/blogpost/_1bx.fnm'
at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirError)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Func`4 createOpenException)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at Lucene.Net.Store.MMapDirectory.OpenInput(String name, IOContext context)
at Lucene.Net.Store.Directory.OpenChecksumInput(String name, IOContext context)
at Lucene.Net.Codecs.Lucene46.Lucene46FieldInfosReader.Read(Directory directory, String segmentName, String segmentSuffix, IOContext context)
at Lucene.Net.Index.SegmentReader.ReadFieldInfos(SegmentCommitInfo info)
at Lucene.Net.Index.IndexWriter.get_FieldNumberMap()
at Lucene.Net.Index.IndexWriter..ctor(Directory d, IndexWriterConfig conf)
new IndexWriter 时会从每个 Segment 中读取 FieldInfo
IndexWriter 构造函数中获取 FieldNumberMap 的语句
globalFieldNumberMap = FieldNumberMap;
FieldNumberMap 的实现
private FieldNumbers FieldNumberMap
{
get
{
FieldNumbers map = new FieldNumbers();
foreach (SegmentCommitInfo info in segmentInfos.Segments)
{
foreach (FieldInfo fi in SegmentReader.ReadFieldInfos(info))
{
map.AddOrGet(fi.Name, fi.Number, fi.DocValuesType);
}
}
return map;
}
}
SegmentReader.ReadFieldInfos 方法的主要实现
return info.Info.Codec.FieldInfosFormat.FieldInfosReader.Read(dir, info.Info.Name, segmentSuffix, IOContext.READ_ONCE);
FieldInfosReader.Read 方法对应的实现 Lucene46FieldInfosReader.cs#L50,找不到的 /zzk/index/blogpost/_1bx.fnm
文件路径就是下面的代码生成的
string fileName = IndexFileNames.SegmentFileName(segmentName, segmentSuffix, Lucene46FieldInfosFormat.EXTENSION);
internal const string EXTENSION = "fnm";
异常是在下面的代码
ChecksumIndexInput input = directory.OpenChecksumInput(fileName, context);
调用 MMapDirectory.OpenInput 方法时抛出的
public override IndexInput OpenInput(string name, IOContext context)
{
EnsureOpen();
var file = new FileInfo(Path.Combine(Directory.FullName, name));
var fc = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return new MMapIndexInput(this, "MMapIndexInput(path=\"" + file + "\")", fc);
}
出问题的索引是从其他路径复制过来的,重新复制丢失的文件即可解决。
异常是在 SegmentReader.cs#L240 处抛出的
– dudu 1年前_1bx.fnm 文件保存的是 field names,fnm 是 field names information 的缩写
– dudu 1年前