Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongo sort by string value that is actually number

Tags:

mongodb

I have collection that contains objects such as this:

{ 
    "_id" : ObjectId("57f00cf47958af95dca29c0c"), 
    "id" : "...", 
    "threadId" : "...", 
    "ownerEmail" : "...@...", 
    "labelIds" : [
       ...
    ], 
    "snippet" : "...", 
    "historyId" : "35699995", 
    "internalDate" : "1422773000000", 
    "headers" : {
        "from" : "...@...", 
        "subject" : "....", 
        "to" : "...@..."
    }, 
    "contents" : {
        "html" : "...."
    }
}

When accessing objects, I want to sort them by iternalDate value, which was supposed to be integer, however it is a string. Is there a way to sort them when fetching even if these are strings? By alphabetic order? Or is there a way to convert them to integer painlessly?

like image 501
Kunok Avatar asked Oct 02 '16 08:10

Kunok


People also ask

How do I sort numbers in MongoDB?

To sort documents in MongoDB, you need to use sort() method. The method accepts a document containing a list of fields along with their sorting order. To specify sorting order 1 and -1 are used. 1 is used for ascending order while -1 is used for descending order.

How do I sort a case insensitive in MongoDB?

This means the only way to sort case insensitive currently is to actually create a specific "lower cased" field, copying the value (lower cased of course) of the sort field in question and sorting on that instead.

How can I sort into that nulls are last ordered in MongoDB?

By adding the boolean property hasPrice, we can specify the order. We sorted the fields that have a value first, which ensures the ones without a price (zero or null values) are sorted last.


2 Answers

Collation is what you need...

db.collection.find()
  .sort({internalDate: 1})
  .collation({locale: "en_US", numericOrdering: true})
like image 197
Dan Loughney Avatar answered Oct 22 '22 15:10

Dan Loughney


It seems to me that the best solution here would be to parse it first as an integer. You could do it using a simple script in javascript like this, using the mongodb client for node:

db.collection.find({}, {internalDate: 1}).forEach(function(doc) {
    db.collection.update(
       { _id: doc._id },
       { $set: { internalDate: parseInt(doc.internalDate) } }
    )
})
like image 28
Alberto Centelles Avatar answered Oct 22 '22 15:10

Alberto Centelles