Lucene.Net 的“System.IndexOutOfRangeException: 索引超出了数组界限”错误
2013-03-18 16:18
549 查看
堆栈信息如下
System.IndexOutOfRangeException: 索引超出了数组界限。
在 Lucene.Net.Search.AnonymousClassIntParser1.ParseInt(String val)
在 Lucene.Net.Search.FieldCacheImpl.IntCache.CreateValue(IndexReader reader, Entry entryKey)
在 Lucene.Net.Search.FieldCacheImpl.Cache.Get(IndexReader reader, Entry key)
在 Lucene.Net.Search.FieldCacheImpl.GetInts(IndexReader reader, String field, IntParser parser)
在 Lucene.Net.Search.FieldCacheImpl.IntCache.CreateValue(IndexReader reader, Entry entryKey)
在 Lucene.Net.Search.FieldCacheImpl.Cache.Get(IndexReader reader, Entry key)
在 Lucene.Net.Search.FieldCacheImpl.GetInts(IndexReader reader, String field, IntParser parser)
在 Lucene.Net.Search.FieldCacheImpl.GetInts(IndexReader reader, String field)
在 Lucene.Net.Search.AnonymousClassIntParser1.ParseInt(String val)
在 Lucene.Net.Search.FieldCacheImpl.IntCache.CreateValue(IndexReader reader, Entry entryKey)
在 Lucene.Net.Search.FieldCacheImpl.Cache.Get(IndexReader reader, Entry key)
在 Lucene.Net.Search.FieldCacheImpl.GetInts(IndexReader reader, String field, IntParser parser)
在 Lucene.Net.Search.FieldCacheImpl.IntCache.CreateValue(IndexReader reader, Entry entryKey)
在 Lucene.Net.Search.FieldCacheImpl.Cache.Get(IndexReader reader, Entry key)
在 Lucene.Net.Search.FieldCacheImpl.GetInts(IndexReader reader, String field, IntParser parser)
在 Lucene.Net.Search.FieldCacheImpl.GetInts(IndexReader reader, String field)
判断
这个错误很常见,一般都是数组引起的,所以可以很容易定位到lucene代码,在FieldCache.cs中的val[0],说明输入可能为null或者string.empty:
public virtual int ParseInt(System.String val) { int shift = val[0] - NumericUtils.SHIFT_START_INT; if (shift > 0 && shift <= 31) throw new FieldCacheImpl.StopFillCacheException(); return NumericUtils.PrefixCodedToInt(val); }
尝试一
AnonymousClassIntParser1是默认给数值字段解码的,当通过FieldCache获取字段值时就会用它来解码还原为数值。lucene不是数据库,没有数据完整性的保证,这个是倒排索引的代价,既然只是绕过空的数值字段,那么用类似int.TryParse()的方式从最下面试试看。修改后错误确实消失了,同时排序也消失了。
尝试二
刚刚说了lucene的设计是没有数据完整性保证的,上面代码中“StopFillCacheException”就是证据,上面的尝试不行后我就开始分析这次调用的过程,也就是FieldCacheImpl.cs。IDictionary<Type, Cache> caches,就是关键的缓存变量,其实一看就知道这个类的作用了。那么再往里看Cache的实现,这里以IntCache为例,这是个内部类,尽在这个字段缓存类中使用。它的作用就是缓存对同一字段的读取,比如文档001的Title,第一次读取后就会被缓存下来,后面的访问都是使用内存中的缓存。
try { do { Term term = termEnum.Term; if (term == null || (System.Object) term.Field != (System.Object) field) break; int termval = parser.ParseInt(term.Text); if (retArray == null) // late init retArray = new int[reader.MaxDoc]; termDocs.Seek(termEnum); while (termDocs.Next()) { retArray[termDocs.Doc] = termval; } } while (termEnum.Next()); } catch (StopFillCacheException) { } catch (IndexOutOfRangeException exc) { } finally { termDocs.Close(); termEnum.Close(); }
上面是我修改后的版本,增加了IndexOutOfRangeException的异常捕捉。搜索结果好了,但是为题还没有根本解决,这里会在第一个出现异常的文档后就终止读取缓存,不过好过不能使用数值字段。完美的解决办法后面会继续跟进。
相关文章推荐
- System.IndexOutOfRangeException: 索引超出了数组界限
- ASP.NET异常具体信息: System.IndexOutOfRangeException: 索引 0 不是为负数,就是大于行数。
- ASP.net 异常详细信息: System.ArgumentOutOfRangeException: 索引超出范围。必须为非负值并小于集合大小。解决方法
- AsParallel \AsQueryable<T>().ToList() [System.ArgumentOutOfRangeException was unhandled" 索引超出范围。必须为非负值并小于集合大小]解决方法
- Android Studio 2.0+发布APK出现ExternalSystemException: String index out of range: -123错误
- java.lang.StringIndexOutOfBoundsException: String index out of range: 0错误的原因 3ff0
- 解决java.lang.IllegalArgumentException: pointerIndex out of range的错误
- DataGrid的ScrollIntoView方法导致 an argument out of range exception(指定的参数已超出有效值的范围)错误的解决
- System.ArgumentOutOfRangeException: 容量超出了最大容量
- System.ArgumentOutOfRangeException: 指定的参数已超出有效值的范围
- IndexError: list index out of range列表索引超出范围
- 警惕麦咖啡的"缓冲区溢出保护"引起的ASP.NET 中 System.OutOfMemoryException 的错误
- Android Studio Error String index out of range 0 字符串索引超出范围
- System.ArgumentOutOfRangeException: 容量超出了最大容量
- 解决java.lang.IllegalArgumentException: pointerIndex out of range 或者 arrayindexoutofboundsexception的错误
- Hibernate query.list()查询发生java.lang.StringIndexOutOfBoundsException: String index out of range: 0错误
- 关于c# 引发了"system.indexOutofRangeException"类型异常,该怎么处理
- DataGridView绑定Ilist对象,出现IndexOutOfRangeException错误的解决方法
- 解决多指操作放大缩小 指针错误 java.lang.IllegalArgumentException: pointerIndex out of range
- System.IndexOutOfRangeException: 在位置 0 处没有任何行。