无符号大整数支持值范围为0到18,446,744,073,709,551,615(264-1),而有符号大整数可以取值范围为−9,223,372,036,854,775,808到9,223,372,036,854,775,807(−263到263-1)。有符号的正数范围足够容纳大型数据集(至少没有已知的Manticore集合超过令人难以置信的9+万亿个文档)。问题只发生在文档ID不是递增值,而是使用无符号大整数进行哈希的情况。对于这些情况,如果无法切换到可以适应有符号类型的哈希,则可以使用简单的转换方法来存储和检索哈希,具体如下所述。
对于实时索引,支持自动生成ID将在不久的将来添加。当RT文档ID不是数据库ID,而是通过哈希或其他方法生成时,随着Manticore侧的自动生成发生,事情会变得更容易。
为什么不同时支持这两种数据类型?
在Manticore中同时支持有符号和无符号ID目前会导致更多的麻烦而不是帮助。例如,一些客户端对响应中的预期数据类型非常严格。发送无符号ID会导致很多混淆,因为客户端被告知要期望有符号的大整数。
如何应对这种变化?
为了与Manticore搜索中的更改保持一致,您的应用程序和数据源可能需要更改文档ID类型。如果ID存储在数据库中,但从未达到有符号的正数范围(263-1),那么事情就很简单:只需将列转换为有符号。如果您的ID确实超过了这个值,数字需要转换为有符号范围。
超过有符号正数范围(263-1)的值可以通过从它们中减去264变为负数:这将把263(第一个超出有符号正数范围的数字)转换为−263,264-1(最大的可能无符号大整数)转换为−1。这种方法也可以用于基于返回无符号大整数的哈希函数生成ID的情况。
例如,在MySQL中,要将无符号大整数转换为适合有符号大整数,我们可以使用IF (id>>63, -(~id) - 1,id)。要将“映射”的有符号数字转换回无符号,我们可以使用IF(signed_id<0, ~0^~signed_id,signed_id)。使用位函数的原因是因为MySQL仅支持大于9223372036854775807(63位)的数字的位函数。
SELECT id,if (id>>63, -(~id) - 1,id) AS mapped_to_signed,
signed_id, if (signed_id<0, ~0^~signed_id,signed_id) AS unsigned_from_mapped
FROM test ORDER BY id
<table>
<thead>
<tr>
If you are using strong-type languages (like .NET), you need to review the code to make sure it will expect the document ids in the search responses to be signed and not unsigned.
We know this change can create some troubles, but it's a one-off change that must be made to enjoy the latest Manticore Search.