Solr中int类型字段值插入后异常变更问题咨询
Solr字段值异常转换问题原因分析
你定义的Solr Schema如下:
<schema name="mysolrcore_01" version="1.6"> <fieldType name="string" class="solr.StrField" /> <fieldType name="text" class="solr.TextField" /> <fieldType name="long" class="solr.LongPointField" /> <fieldType name="int" class="solr.IntPointField" /> <uniqueKey>id</uniqueKey> <uniqueKey>item_key</uniqueKey> <field name="_version_" type="long" indexed="true" stored="true" multiValued="false" /> <field name="_root_" type="string" indexed="true" stored="false" /> <field name="id" type="string" indexed="true" stored="true" required="false" multiValued="false" /> <field name="sqlid" type="int" indexed="true" stored="true" required="true" multiValued="false" /> <field name="mongoid" type="string" indexed="true" stored="true" required="true" multiValued="false" /> <field name="item_lang" type="string" indexed="false" stored="true" required="true" multiValued="false" /> <!-- Field "published" to be noted. I intend to store an UNIX timestamp here. --> <field name="published" type="int" indexed="true" stored="true" required="true" multiValued="false" /> <field name="item_key" type="string" indexed="true" stored="true" required="true" /> <field name="content_en" type="text" indexed="true" stored="false" /> </schema>
插入以下文档时:
{ "sqlid":99, "mongoid":"63c69aa7dc7c000062000267", "item_key":"inferno", "item_lang":"en", "published":-2347142400, "content_en":"Some content" }
实际存储的文档中published字段值异常:
{ "sqlid":99, "mongoid":"63c69aa7dc7c000062000267", "item_key":"inferno", "item_lang":"en", "published":1947824896, "id":"b818cfe9-f84a-4c08-a9c0-cea988b0c437", "_version_":1755274390346399744 }
问题核心原因
这是整数溢出导致的问题:
published字段指定的类型是int,对应Solr的solr.IntPointField,底层使用Java的int类型存储。- Java中
int的取值范围是 -2147483648 到 2147483647(即-231到231-1)。 - 插入的
published值-2347142400小于-2147483648,超出了int类型的最小值范围,触发整数溢出。溢出后数值会按2^32(int类型的无符号总范围)循环取模,最终得到1947824896(计算方式:4294967296 + (-2347142400) = 1947824896)。
之前插入的正负值正常,是因为那些数值都在int的合法取值范围内,没有触发溢出。
解决方案
将published字段的类型从int改为long(对应Solr的solr.LongPointField):
<field name="published" type="long" indexed="true" stored="true" required="true" multiValued="false" />
long类型的取值范围是-9223372036854775808到9223372036854775807,完全能覆盖所有可能的Unix时间戳(包括1970年之前的远古时间)。
内容的提问来源于stack exchange,提问作者sariDon
相关产品推荐
相关产品推荐

