错误都出现在4.0升级到4.8时。调用栈如下: Caused by: java.lang.IllegalArgumentException: maxValue must be non-negative (got: -1) at org.apache.lucene.util.packed.PackedInts.bitsRequired(PackedInts.java:1180) at org.apache.lucene.codecs.lucene41.ForUtil.bitsRequired(ForUtil.java:243) at org.apache.lucene.codecs.lucene41.ForUtil.writeBlock(ForUtil.java:164) at org.apache.lucene.codecs.lucene41.Lucene41PostingsWriter.addPosition(Lucene41PostingsWriter.java:368) at org.apache.lucene.codecs.PostingsConsumer.merge(PostingsConsumer.java:123) at org.apache.lucene.codecs.TermsConsumer.merge(TermsConsumer.java:164) at org.apache.lucene.codecs.FieldsConsumer.merge(FieldsConsumer.java:72) at org.apache.lucene.index.SegmentMerger.mergeTerms(SegmentMerger.java:389) at org.apache.lucene.index.SegmentMerger.merge(SegmentMerger.java:112) at org.apache.lucene.index.IndexWriter.mergeMiddle(IndexWriter.java:4132) at org.apache.lucene.index.IndexWriter.merge(IndexWriter.java:3728) at org.apache.lucene.index.ConcurrentMergeScheduler.doMerge(ConcurrentMergeScheduler.java:405) at org.apache.lucene.index.ConcurrentMergeScheduler$MergeThread.run(ConcurrentMergeScheduler.java:482)
看代码后,在PostingsConsumer 120行附近,final int position = postingsEnum.nextPosition();,这个position是负的,所以报错。看这附近的代码,知道是对索引词的在文档中的位置信息进行压缩。可是词在文档中的位置不应该是负的,于是报错。问题是,为什么这里会出现负的位置,只能解释是数据问题。一个解决的办法是跳过为负的位置,如此升级确实成功了,只是不知道有没有什么副作用。
一个明显的解答是6的阶乘,也就是720次,可是其中有很多种涂色,经过旋转后是一样的,所以这是错的。看到这题,立刻想到了魔方,之后想到了骰子,考虑到骰子更加直观,就用骰子。思考之后,其实挺简单的。把1这面朝上,那么1的对面,也就是底面有5种可能的情况。之后再看侧面的情况,对于侧面,固定一面之后,它的对面还有3中可能的情况,之后剩下两个侧面,有2种情况。所以一共有5 x 3 x 2 = 30种情况。这题一个难点是最开始的1这面的选择,以及侧面时,固定一面的选择。对于1这面的选择,是不能算概率的,因为无论怎么排,总是可以把1这面朝上。而对于侧面时固定一面,这固定一面也是不能算概率的,因为无论怎么排,都可以固定一面。
之后跳转到DoCommandUpdate,UpdateAttributes 在其中发现这样一句话: // this is a hack // Query parser tries to detect an attribute type. And this is wrong because, we should // take attribute type from schema. Probably we’ll rewrite updates in future but // for now this fix just works. // Fixes cases like UPDATE float_attr=1 WHERE id=1; 也就是说,Sphinx更新属性时,没有去读取配置文件。而只是根据上面代码中的设定去读取更新信息,所以没有办法读取负数。一个主要的原因是,Sphinx没有32位整型数据的概念,只有32位无符号整型的概念。