#php #mongodb
#php #mongodb
Вопрос:
У меня есть API, который ожидает, что определенное поле будет иметь NumberLong
значения. Поэтому при записи в базу данных with с помощью драйвера PHP эти значения должны быть записаны как type NumberLong
. Здесь говорится , что
Когда драйвер кодирует целое число PHP в BSON (здесь ), мы используем макрос, который записывает 64-разрядное или 32-разрядное целое число в зависимости от диапазона целочисленного значения PHP. Это аналогично поведению сервера, где результаты вычисления целых чисел (например, из $inc ) будут использовать наименьший тип, способный содержать значение, и при необходимости переходить к большому типу.
Насколько я могу судить, это все еще так.
Эта программа воссоздает проблему:
// document with _id=0 looks like: {"_id": 0, "number": NumberLong(42)}
$collection = (new DBMongo())->selectCollection("test");
$docs = $collection->find(["_id" => 0]);
foreach ($docs as $doc) {
$doc["_id"] = 1;
$doc["number"] = 42;
$collection->insertOne($doc);
}
// document with _id=1 looks like: {"_id": 1, "number": 42}
Цель состоит в том, чтобы «скопировать» некоторые документы, внеся простые изменения. PHP используется по историческим причинам.
Как я могу заставить "number"
поле в приведенном выше документе _id=1 быть NumberLong(42)
таким, какое оно есть с _id= 0 ?
Комментарии:
1. Это кажется невозможным.
2. Это довольно обескураживающе слышать.
Ответ №1:
Я проанализировал некоторый расширенный json с помощью драйвера php, и информация о типе была потеряна, что привело меня к мысли, что драйвер не предоставляет простого способа сохранения типов. Int64 содержит примечание о том, что оно не может быть создано напрямую.
С учетом сказанного, драйвер технически не обязан сохранять информацию о типе для своей собственной функциональности, за исключением идентификаторов курсоров, которые должны быть отправлены на сервер в виде int64. Исходя из этого, я предлагаю следующее:
- Выполните поиск и получите курсор. Извлеките его идентификатор курсора.
- Сериализуйте идентификатор курсора. По сути, это int64.
- Посмотрите на сериализованное представление, чтобы выяснить, где находится значение.
- Создайте новое сериализованное представление со значением int64, которое вы хотите.
- Десериализуйте идентификатор курсора из этого представления.
- Используйте идентификатор курсора в своей операции, куда вы хотите отправить int64.
Несколько сумасшедшая идея, но она может сработать.
Комментарии:
1. Я попробую при первой возможности и сообщу об этом. Спасибо.