# Миграция на Manticore 3: идентификаторы документов

В этой статье мы обсуждаем изменение типа данных идентификатора документа в Manticore Search 3.0.

В предыдущих версиях идентификаторы документов были беззнаковыми большими целыми числами. В версии 3.0 это изменилось, так как мы перешли на знаковые большие целые числа. Причина этого решения заключалась в том, чтобы сделать идентификаторы документов единообразными с атрибутами типа bigint, которые являются знаковыми, поскольку в большинстве случаев даже знаковые bigint должны быть достаточными, и к тому же мы переходим к автоматически генерируемым ID.

Однако в редких случаях это изменение может стать проблемой, и в этой статье мы подробнее рассмотрим различия и способы преодоления проблемы, если она возникнет.

Беззнаковые большие целые числа поддерживают значения от 0 до **18,446,744,073,709,551,615** ( 2<sup>64</sup>-1), тогда как знаковые большие целые числа могут принимать значения от **−9,223,372,036,854,775,808** до **9,223,372,036,854,775,80**7 ( −2<sup>63</sup> до 2<sup>63</sup>−1) ). Положительный диапазон знаковых чисел достаточно велик, чтобы вместить большие наборы данных (по крайней мере, не известно ни одной коллекции Manticore, превышающей невероятные 9+ квадриллионов документов). Проблема возникает только тогда, когда идентификатор документа не является увеличивающимся значением, а представляет собой хеш, использующий беззнаковый большой целый. В таких случаях, если невозможно перейти на хеш, который помещается в знаковый тип, можно использовать довольно простое преобразование для хранения и получения хешей, как объясняется ниже.

В случае RealTime‑индексов поддержка автоматически генерируемых идентификаторов будет добавлена в ближайшее время. В случаях, когда RT‑идентификатор документа не был получен из базы данных, а был сгенерирован (хешем или другими методами), ситуация упростится, когда автоматическая генерация будет происходить на стороне Manticore.

Почему не поддерживать оба типа данных?

Поддержка как знаковых, так и беззнаковых идентификаторов в Manticore сейчас вызвала бы больше проблем, чем пользы. Например, некоторые клиенты строго ожидают определённые типы данных в ответах. Отправка беззнаковых значений в ответах вызовет много путаницы, поскольку клиенты ожидают знаковый большой целый.

Как справиться с этим изменением?

Чтобы соответствовать изменению в Manticore Search, тип идентификатора документа может потребовать изменения в вашем приложении и источниках данных. Если идентификаторы хранятся в базе данных, но они никогда не достигают положительного знакового диапазона ( **2<sup>63</sup> -1**), то всё просто: достаточно преобразовать столбец в знаковый тип. Если ваши идентификаторы превышают это значение, числа необходимо преобразовать в знаковые диапазоны.

Значения, превышающие положительный знаковый диапазон ( **2<sup>63</sup> -1**), можно превратить в отрицательные числа, вычтя из них  **2<sup>64</sup>**: это преобразует **2<sup>63</sup>** (первое число выше положительного знакового диапазона) в **-2<sup>63</sup>**, а **2<sup>64</sup>-1** (наибольший возможный беззнаковый большой целый) в **-1**. Это также можно использовать, если вы генерируете идентификаторы на основе хеш-функции, возвращающей беззнаковые большие целые.

Например, в MySQL для преобразования беззнакового большого целого в знаковый большой целый можно использовать `IF (id>>63, -(~id) - 1,id)`. Чтобы обратно преобразовать «отображённое» знаковое число в беззнаковое, можно использовать `IF(signed_id<0, ~0^~signed_id,signed_id)`. Причина использования битовых функций заключается в том, что MySQL поддерживает битовые функции только для чисел больше 9223372036854775807 (63 бита).


```bash
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>
<th class="col0">id</th>
<th class="col1">unsigned_to_mapped</th>
<th class="col2">signed_id</th>
<th class="col3">unsigned_from_mapped</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col0">0</td>
<td class="col1">0</td>
<td class="col2">0</td>
<td class="col3">0</td>
</tr>
<tr>
<td class="col0">1</td>
<td class="col1">1</td>
<td class="col2">1</td>
<td class="col3">1</td>
</tr>
<tr>
<td class="col0">9223372036854775807</td>
<td class="col1">9223372036854775807</td>
<td class="col2">9223372036854775807</td>
<td class="col3">9223372036854775807</td>
</tr>
<tr>
<td class="col0">9223372036854775808</td>
<td class="col1">-9223372036854775808</td>
<td class="col2">-9223372036854775808</td>
<td class="col3">9223372036854775808</td>
</tr>
<tr>
<td class="col0">9223372036854775809</td>
<td class="col1">-9223372036854775807</td>
<td class="col2">-9223372036854775807</td>
<td class="col3">9223372036854775809</td>
</tr>
<tr>
<td class="col0">18446744073709551613</td>
<td class="col1">-3</td>
<td class="col2">-3</td>
<td class="col3">18446744073709551613</td>
</tr>
<tr>
<td class="col0">18446744073709551614</td>
<td class="col1">-2</td>
<td class="col2">-2</td>
<td class="col3">18446744073709551614</td>
</tr>
<tr>
<td class="col0">18446744073709551615</td>
<td class="col1">-1</td>
<td class="col2">-1</td>
<td class="col3">18446744073709551615</td>
</tr>
</tbody>
</table>


Если вы используете строго типизированные языки (например, .NET), вам необходимо проверить код, чтобы убедиться, что он ожидает знаковые идентификаторы документов в ответах поиска, а не беззнаковые.

Мы знаем, что это изменение может вызвать некоторые проблемы, но это единовременное изменение, которое необходимо выполнить, чтобы воспользоваться последней версией Manticore Search.
