Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB type update from NumberLong to String

I've imported CSV file to my mongodb. CSV have separators as needed to mongo and was received from MySQL database with this query:
SELECT * FROM csgo_users INTO OUTFILE 'b1.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
Also I've tried to receive CSV from Sequel Pro with it's export functions.
In my csv I have field with 17 characters length. In MySQL database this field has type VARCHAR but contains 17-digits number.
After importing csv to mongo I got this field with type NumberLong, but I want it to be string.
I've tried so far to:

  • Change type in MySQL from varchar to text.
  • Tried to import csv with additional flags --headerline and --columnsHaveTypes
  • Also I've tried to add separate fields without top line, with tag --fields.
  • Tried commands as this:

    db.csgo_users.find({"steam_id": {$type: 18}})
           .toArray()
           .map(function(v){
               v.steam_id = new String(v); 
               db.csgo_users.save(v)
            })
    

or this:

db.csgo_users.find({"steam_id": {$type: 18}})
  .toArray()
  .map(function(v){
     v.steam_id = new String(v.toSring());
     db.csgo_users.save(v)
  })


- I've tried a lot of solutions with forEach() like this or this or this etc.


For the last one example of my tries I've got not string, but Object, {"N",u","m","b","e","r","L","o","n","g"..} but I want it to be "123456789", not Object.
I'm using MongoDB 3.4 docs.
So, my question is, how to change "field" type from NumberLong to String?

like image 330
Grynets Avatar asked Mar 02 '17 19:03

Grynets


People also ask

How to find and replace numberlong type field in MongoDB?

Find and replace NumberLong type field in MongoDB? Use $set operator along with update () for this. Let us first create a collection with documents. Here we have set one field as NumberLong − Following is the query to display all documents from a collection with the help of find () method −

What are the available BSON types in MongoDB?

The types specified in the array can be either numeric or string aliases. See Querying by Multiple Data Type for an example. Available Types describes the BSON types and their corresponding numeric and string aliases. $isNumber - checks if the argument is a number. New in MongoDB 4.4 $type (Aggregation) - returns the BSON type of the argument.

How to convert numberlong to string in MySQL?

To convert NumberLong to String, you can use valueOf () as well − Let us implement both the above syntaxes. Following is the query to convert NumberLong to String with toString () −

How does $type array work in MongoDB?

With MongoDB 3.6 and later, querying for $type: "array" returns documents where the field itself is an array. Prior to MongoDB 3.6, $type: "array" returned documents where the field is an array containing at least one element of type array. For example, given the following documents:


2 Answers

You can use valueOf() to get the value of a NumberLong as a javascript number value.

Casting NumberLong to Number :

NumberLong('5').valueOf() // 5

Then, you can then use easilly toString() on your number to get the String value.

Casting NumberLong to String :

NumberLong('5').valueOf().toString() // "5"
like image 161
Julien TASSIN Avatar answered Oct 04 '22 01:10

Julien TASSIN


The type NumberLong exists for a reason, to handle huge numbers, similar to BigInt on SQL. MongoDB relies on JavaScript which have at most 53 bits for integers, in ES6 the largest exact integral value is 253-1, or 9007199254740991, for this reason, "converting" from NumberLong to a simple string isn't as simple as the previous answer, here is an example:

var huge = NumberLong("987654321987654321");
huge.valueOf(); // 987654321987654300
huge.toString(); // NumberLong("987654321987654321")
huge.valueOf().toString(); // 987654321987654300

With this example, it is clear that JavaScript is rounding up the numbers while using valueOf(), and lacking any sane response and documentation, I came with a workaround for this situation, using RegEx to remove any non numerical characters from the toString() function:

huge.toString().replace(/[^\d]/g, '') // 987654321987654321

It isn't pretty, but it works, any other better solution is always appreciated. As a bonus fact, using JSON.stringify converts the value into an object using the special char $ to represent the function to call while processing the value, the way MongoDB handles this issues while dealing with common day to day JSON objects:

JSON.stringify(huge) // {"$numberLong":"987654321987654321"}

Update: The right way of converting data with MongoDB is with aggregations using a projection:

db.getCollection('mycollection').aggregate([
    {$match: {
        /* your match query object */
    }},
    {$project: {
        _id: 0, // to ignore the document id
        myStringObj: {$toString: '$myNumberLongObj'} // from NumberLong to String
    }},
], {allowDiskUse: true});
like image 36
Rodrigo Polo Avatar answered Oct 04 '22 01:10

Rodrigo Polo