1

I have a collection "logs" and I need to sort it by most recent first. With findOne() I do:

.sort($natural: -1)

However this is not doing anything now.

  db('logs').find({'userId': userId}).sort({ $natural: -1}).toArray(function (err, result) {
    if (err) console.error(err)
    if (result.length > 0) {
      console.log('Found ' + result.length + ' log entries', result)
      if (callback) callback(result)
    } else {
      console.log('No log entries for ' + userId, userId)
      if (callback) callback(null)
    }
  })

This outputs the same as $natural: 1. Or if I skip sort() all together.

Collection:

{_id: "5c044d13f4c6db53a047fe37", dateTime: "2018-12-02 22:22", userId: 5, event: "Failed to update Media Package sale", info: {userId: 5, AmountOfPrePaidItems: 1}}
{_id: "5c044d2bf4c6db53a047fe38", dateTime: "2018-12-02 22:22", userId: 5, event: "Failed to update Media Package sale", info: {userId: 5, AmountOfPrePaidItems: 0}}
{_id: "5c044d56f4c6db53a047fe39", dateTime: "2018-12-02 22:23", userId: 5, event: "Failed to update Media Package sale", info: {userId: 5, AmountOfPrePaidItems: 1}}

Using Atlas mongoDB 4.0.4

Edit 1: .sort( _id: -1) also gives same output order

1
  • If your sorting was working before, I'd say it's pretty likely that you're accidentally reordering your results outside of the code you're showing. Commented Dec 3, 2018 at 2:28

1 Answer 1

6

For what you are trying to do you should simply use:

db('logs').find({'userId': userId}).sort({ _id: -1 })

if you want to get the most recent first since _id contains the date etc.

As far as $natural goes:

The $natural parameter returns items according to their natural order within the database. This ordering is an internal implementation feature, and you should not rely on any particular structure within it.

Using your sample data:

db.getCollection('items').find().sort({ _id: -1}) 

You get:

/* 1 */
{
    "_id" : "5c044d56f4c6db53a047fe39",
    "dateTime" : "2018-12-02 22:23",
    "userId" : 5,
    "event" : "Failed to update Media Package sale",
    "info" : {
        "userId" : 5,
        "AmountOfPrePaidItems" : 1
    }
}

/* 2 */
{
    "_id" : "5c044d2bf4c6db53a047fe38",
    "dateTime" : "2018-12-02 22:22",
    "userId" : 5,
    "event" : "Failed to update Media Package sale",
    "info" : {
        "userId" : 5,
        "AmountOfPrePaidItems" : 0
    }
}

/* 3 */
{
    "_id" : "5c044d13f4c6db53a047fe37",
    "dateTime" : "2018-12-02 22:22",
    "userId" : 5,
    "event" : "Failed to update Media Package sale",
    "info" : {
        "userId" : 5,
        "AmountOfPrePaidItems" : 1
    }
}

Notice that top document is:

"_id" : "5c044d56f4c6db53a047fe39",
"dateTime" : "2018-12-02 22:23",

Doing:

db.getCollection('items').find().sort({ _id: 1})

Notice that:

"_id" : "5c044d13f4c6db53a047fe37",
"dateTime" : "2018-12-02 22:22",

Is the top document.

Sign up to request clarification or add additional context in comments.

5 Comments

Hi @akrion! I have tried this too. But I get the output in the same order. I am thinking it has something to do with toArray()
Interesting since I used your data and got different result. See updated answer.
In the mongo shell I get the same result as you, it works. But my case is in a NodeJS environment, and using .toArray()
@RuneAspvik I get exactly the same results in nodeJS with this: db.collection('items').find({}).sort({ _id: -1}).toArray((err, res) => ... where items is the exact collection you posted.
My initial solution worked, so did yours. I had a replica route in my server that caught the request before the one I was working on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.