Есть ли шанс примера - изменить тип поля с int на строку (или наоборот) из оболочки?
Алистер Булман
30
в случае Int32-> String new String(x.bad)создает коллекцию Strings со значением 0-index-item x.bad. Вариант ""+x.bad, описанный Симоной, работает как нужно - создает значение String вместо Int32
Dao
Приведенный выше код преобразует данные поля из двойного в массив вместо двойного в строку. Мои фактические данные были в этом формате: 3.1, тогда как код simone для меня работает нормально
Pankaj Khurana
2
Была ситуация, когда мне нужно было преобразовать поле _id, а не конфликтовать с другими индексами:db.questions.find({_id:{$type:16}}).forEach( function (x) { db.questions.remove({_id:x._id},true); x._id = ""+x._id; db.questions.save(x); });
Мэтт Молнар
@SundarBons да, вы переписываете поле в своей базе данных, это большое дело, независимо от того, как вы это делаете. Если бы вы использовали SQL, и это была большая таблица, вам, вероятно, потребовалось бы некоторое время простоя.
Это здорово - знаете ли вы, как бы вы конвертировали строку (например, валюту типа «1.23») в целое число 123? Я предполагаю, что вам придется анализировать его как число с плавающей запятой или десятичное число, умножить его на 100, а затем сохранить как целое число, но я не могу найти нужные документы для этого. Спасибо!
Брайан Армстронг
На самом деле это работает хорошо. Но у меня есть приложение, работающее с mongoid 2.4.0-stable, у которого есть такие поля, как field: customer_count, type: Integer и валидация as validates_numericity_of: customer_count, которая работала нормально. Теперь, когда я обновляюсь до mongoid до версии 3.0.16, когда я присваиваю строковое значение, он автоматически преобразует его в 0. без ошибок. Я хочу выдать ошибку при неправильном назначении данных, это поведение оказалось странным для меня.
Swapnil Chincholkar
4
Я запустил это и получил ошибку: Ошибка: не удалось преобразовать строку в целое число (оболочка): 1
Mittenchops
И если вам нужно преобразовать строку (или «обычное» 32-разрядное целое число) в 64-разрядное целое число, используйте NumberLongздесь:db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
Первая часть { a : { $type: 1 } }- это запрос на совпадение:
Он фильтрует, какие документы обновлять.
В этом случае, поскольку мы хотим преобразовать "a"в строку, когда ее значение равно double, это соответствует элементам, для которых "a"имеет тип 1(double)).
В этой таблице представлены коды, представляющие различные возможные типы.
Вторая часть [{ $set: { a: { $toString: "$a" } } }]- конвейер агрегации обновлений:
Обратите внимание на квадратные скобки, обозначающие, что этот запрос на обновление использует конвейер агрегации.
$setэто новый оператор агрегирования ( Mongo 4.2), который в этом случае изменяет поле.
Это может быть просто прочитано как "$set"значение, "a"чтобы "$a"преобразовать "$toString".
Что действительно нового здесь, так это возможность Mongo 4.2ссылаться на сам документ при его обновлении: новое значение для "a"основывается на существующем значении "$a".
Также обратите внимание, "$toString"что это новый оператор агрегации, введенный в Mongo 4.0.
Не забывайте { multi: true }, иначе будет обновлен только первый соответствующий документ.
В случае , если ваш бросок не из двойной строки, у вас есть выбор между различными операторами преобразования введенных в Mongo 4.0таких , как $toBool, $toInt...
И если для вашего целевого типа нет выделенного конвертера, вы можете заменить его { $toString: "$a" }на $convertоперацию, { $convert: { input: "$a", to: 2 } }значение которой toможно найти в этой таблице :
db.collection.update({ a :{ $type:1}},[{ $set:{ a:{ $convert:{ input:"$a", to:2}}}}],{ multi:true})
db.collection.updateMany( { a : { $type: 1 } }, [{ $set: { a: { $toString: "$a" } } }] )- multi : trueможно избежать с помощьюupdateMany
Васим
1
Начиная с 2020 года, использование $ convert должно быть правильным методом для этого, так как он должен быть намного более эффективным (и более простым в использовании для загрузки).
Халил Раванна
10
все ответы до сих пор используют некоторую версию forEach, перебирая все элементы коллекции на стороне клиента.
Однако вы можете использовать обработку на стороне сервера MongoDB, используя агрегатный конвейер и $ out stage как:
этап $ out атомарно заменяет существующую коллекцию новой коллекцией результатов.
Чтобы преобразовать поле строкового типа в поле даты, вам нужно будет перебрать курсор, возвращаемый find()методом, используя forEach()метод, в цикле преобразовать поле в объект Date, а затем обновить поле с помощью $setоператора.
Воспользуйтесь преимуществом Bulk API для массовых обновлений, которые обеспечивают более высокую производительность, поскольку вы будете отправлять операции на сервер партиями, скажем, 1000, что даст вам лучшую производительность, поскольку вы не отправляете каждый запрос на сервер, только один раз в каждом 1000 запросов.
Следующее демонстрирует этот подход, первый пример использует Bulk API, доступный в версиях MongoDB >= 2.6 and < 3.2. Он обновляет все документы в коллекции, изменяя все created_atполя на поля даты:
var bulk = db.collection.initializeUnorderedBulkOp(),
counter =0;
db.collection.find({"created_at":{"$exists":true,"$type":2}}).forEach(function(doc){var newDate =newDate(doc.created_at);
bulk.find({"_id": doc._id }).updateOne({"$set":{"created_at": newDate}});
counter++;if(counter %1000==0){
bulk.execute();// Execute per 1000 operations and re-initialize every 1000 update statements
bulk = db.collection.initializeUnorderedBulkOp();}})// Clean up remaining operations in queueif(counter %1000!=0){ bulk.execute();}
Следующий пример относится к новой версии MongoDB, 3.2которая с тех пор устарела Bulk API и предоставила более новый набор apis с использованием bulkWrite():
Мне нужно изменить тип данных нескольких полей в коллекции, поэтому я использовал следующее для внесения нескольких изменений типа данных в коллекцию документов. Ответ на старый вопрос, но может быть полезным для других.
db.mycoll.find().forEach(function(obj){if(obj.hasOwnProperty('phone')){
obj.phone =""+ obj.phone;// int or longint to string}if(obj.hasOwnProperty('field-name')){
obj.field-name =newNumberInt(obj.field-name);//string to integer}if(obj.hasOwnProperty('cdate')){
obj.cdate =newISODate(obj.cdate);//string to Date}
db.mycoll.save(obj);});
You can easily convert the string data type to numerical data type.Don't forget to change collectionName &FieldName.for ex :CollectionNmae:Users&FieldName:Contactno.
toString
поле для какого-либо документа, вот небольшая программа, которую я сделал / использовал .Ответы:
Единственный способ изменить
$type
данные - это обновить данные, в которых данные имеют правильный тип.В этом случае похоже, что вы пытаетесь изменить значение
$type
с 1 (double) на 2 (string) .Поэтому просто загрузите документ из БД, выполните приведение (
new String(x)
), а затем сохраните документ снова.Если вам нужно сделать это программно и полностью из оболочки, вы можете использовать
find(...).forEach(function(x) {})
синтаксис.В ответ на второй комментарий ниже. Измените поле
bad
с числа на строку в коллекцииfoo
.источник
new String(x.bad)
создает коллекцию Strings со значением 0-index-itemx.bad
. Вариант""+x.bad
, описанный Симоной, работает как нужно - создает значение String вместо Int32db.questions.find({_id:{$type:16}}).forEach( function (x) { db.questions.remove({_id:x._id},true); x._id = ""+x._id; db.questions.save(x); });
Преобразовать строковое поле в целое число:
Преобразовать целочисленное поле в строку:
источник
NumberLong
здесь:db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
Для преобразования строки в int.
Для преобразования строки в двойное число.
Для поплавка:
источник
radix
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…new NumberInt()
источник
Начав
Mongo 4.2
,db.collection.update()
можно принять агрегационный конвейер, наконец, разрешив обновление поля на основе его собственного значения:Первая часть
{ a : { $type: 1 } }
- это запрос на совпадение:"a"
в строку, когда ее значение равно double, это соответствует элементам, для которых"a"
имеет тип1
(double)).Вторая часть
[{ $set: { a: { $toString: "$a" } } }]
- конвейер агрегации обновлений:$set
это новый оператор агрегирования (Mongo 4.2
), который в этом случае изменяет поле."$set"
значение,"a"
чтобы"$a"
преобразовать"$toString"
.Mongo 4.2
ссылаться на сам документ при его обновлении: новое значение для"a"
основывается на существующем значении"$a"
."$toString"
что это новый оператор агрегации, введенный вMongo 4.0
.Не забывайте
{ multi: true }
, иначе будет обновлен только первый соответствующий документ.В случае , если ваш бросок не из двойной строки, у вас есть выбор между различными операторами преобразования введенных в
Mongo 4.0
таких , как$toBool
,$toInt
...И если для вашего целевого типа нет выделенного конвертера, вы можете заменить его
{ $toString: "$a" }
на$convert
операцию,{ $convert: { input: "$a", to: 2 } }
значение которойto
можно найти в этой таблице :источник
db.collection.updateMany( { a : { $type: 1 } }, [{ $set: { a: { $toString: "$a" } } }] )
-multi : true
можно избежать с помощьюupdateMany
все ответы до сих пор используют некоторую версию forEach, перебирая все элементы коллекции на стороне клиента.
Однако вы можете использовать обработку на стороне сервера MongoDB, используя агрегатный конвейер и $ out stage как:
пример:
источник
Чтобы преобразовать поле строкового типа в поле даты, вам нужно будет перебрать курсор, возвращаемый
find()
методом, используяforEach()
метод, в цикле преобразовать поле в объект Date, а затем обновить поле с помощью$set
оператора.Воспользуйтесь преимуществом Bulk API для массовых обновлений, которые обеспечивают более высокую производительность, поскольку вы будете отправлять операции на сервер партиями, скажем, 1000, что даст вам лучшую производительность, поскольку вы не отправляете каждый запрос на сервер, только один раз в каждом 1000 запросов.
Следующее демонстрирует этот подход, первый пример использует Bulk API, доступный в версиях MongoDB
>= 2.6 and < 3.2
. Он обновляет все документы в коллекции, изменяя всеcreated_at
поля на поля даты:Следующий пример относится к новой версии MongoDB,
3.2
которая с тех пор устарела Bulk API и предоставила более новый набор apis с использованиемbulkWrite()
:источник
Чтобы преобразовать int32 в строку в монго, не создавая массив, просто добавьте "" к своему номеру :-)
источник
Что действительно помогло мне изменить тип объекта в MondoDB, так это простая строка, возможно, упомянутая ранее здесь:
Пользователи - это моя коллекция, а age - это объект, в котором вместо целого числа была строка (int32).
источник
Мне нужно изменить тип данных нескольких полей в коллекции, поэтому я использовал следующее для внесения нескольких изменений типа данных в коллекцию документов. Ответ на старый вопрос, но может быть полезным для других.
источник
Попробуйте этот запрос ..
источник
Демо изменить тип поля середины от строки до монго objectId с помощью мангуста
Mongo ObjectId - это еще один пример таких стилей, как
Число, строка, логическое значение, которые надеются, что ответ поможет кому-то еще.
источник
Я использую этот скрипт в консоли mongodb для преобразования строки в плавающее число ...
И этот в php)))
источник
в моем случае я использую следующие
источник