Lucene問題之:java.lang.ArrayIndexOutOfBoundsException
阿新 • • 發佈:2018-12-13
FacetField的使用
在使用FacetField建立的field後,後面使用它進行統計查詢的時候,總是報出如下的異常資訊:
java.lang.ArrayIndexOutOfBoundsException: 2
at org.apache.lucene.facet.taxonomy.IntTaxonomyFacets.increment(IntTaxonomyFacets.java:88)
at org.apache.lucene.facet.taxonomy.IntTaxonomyFacets.increment(IntTaxonomyFacets.java:80 )
at org.apache.lucene.facet.taxonomy.FastTaxonomyFacetCounts.count(FastTaxonomyFacetCounts.java:88)
at org.apache.lucene.facet.taxonomy.FastTaxonomyFacetCounts.<init>(FastTaxonomyFacetCounts.java:54)
at org.apache.lucene.facet.taxonomy.FastTaxonomyFacetCounts.<init>(FastTaxonomyFacetCounts. java:44)
跟蹤原始碼發現是如下兩個地方的值不一致導致的:
public abstract class IntTaxonomyFacets extends TaxonomyFacets {
/** Per-ordinal value. */
private final int[] values;
private final IntIntScatterMap sparseValues;
FastTaxonomyFacetCounts類中下面程式碼中計算出的ord值超出了上面程式碼中values的長度。
for (int doc = it.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = it.nextDoc()) {
final BytesRef bytesRef = dv.binaryValue();
byte[] bytes = bytesRef.bytes;
int end = bytesRef.offset + bytesRef.length;
int ord = 0;
int offset = bytesRef.offset;
int prev = 0;
while (offset < end) {
byte b = bytes[offset++];
if (b >= 0) {
prev = ord = ((ord << 7) | b) + prev;
increment(ord);
ord = 0;
} else {
ord = (ord << 7) | (b & 0x7F);
}
}
}
為什麼會超出呢,我們繼續往下面分析。那麼這個int[] values裡面到底是存的是什麼呢?我們繼續看下面的程式碼:
protected IntTaxonomyFacets(String indexFieldName, TaxonomyReader taxoReader, FacetsConfig config, FacetsCollector fc) throws IOException {
super(indexFieldName, taxoReader, config);
if (useHashTable(fc, taxoReader)) {
sparseValues = new IntIntScatterMap();
values = null;
} else {
sparseValues = null;
values = new int[taxoReader.getSize()];
}
}
從上面的程式碼中我們可以看出它的值為new int[taxoReader.getSize()],是由taxoReader.getSize()決定大小的。再看TaxonomyReader中有如下的一個size
/**
* Returns the number of categories in the taxonomy. Note that the number of
* categories returned is often slightly higher than the number of categories
* inserted into the taxonomy; This is because when a category is added to the
* taxonomy, its ancestors are also added automatically (including the root,
* which always get ordinal 0).
*/
public abstract int getSize();
它的實現類DirectoryTaxonomyReader中的方法:
@Override
public int getSize() {
ensureOpen();
return indexReader.numDocs();
}
到這裡大家應該能夠看出這個values的長度就是當前reader下的文件數決定的。繼續往下跟蹤程式碼發現:
TaxonomyWriter生成的上面的檔案異常,只有一個segments,而正常的像下面這樣有兩個segments:
到這裡才聯想起來我在程式碼中的TaxonomyWriter可能沒有提交,去檢查,發現的確沒有提交,加上commit之後問題解決。
後記
文中values的長度是由每個segments中的文件數之後決定的,本文中我明明只有一個文件,TaxonomyWriter為什麼會有兩個segment,一個segment裡面的文件數是1個,還有一個裡面的文件數是4個。這裡就沒有搞明白為什麼會多出這4個出來。有知道的朋友可以指點下。