mongodb: $sort and $limit behaves weird with undefined

TDaver

I'm on latest version (2.6.3 I believe) of mongodb.

I have the following aggregate:

{
   "$project": {
        "summary": 1,  
        "priority": 1,
        "sortDate": {
           "$ifNull": [
              "$targetDate",
              "$deadlineDate"
           ]
        }
   }
},
{
  "$sort": {
      "priority": -1,
      "sortDate": 1
   }
}

Some objects in the collection have both targetDate and deadlineDate undefined.

Now here is the weird thing. If I run this, I get all eleven back:

  1. The one with priority 3

  2. One with priority 2 and no sortDate

  3. Another one with priority 2 and no sortDate

  4. The ones with priority 2 and sortDate (in correct order)

  5. ... etc priority 1

I understand why undefined is before the valued ones, even if I don't like it. But, if I add

{ "$limit": 2 }

to the aggregation pipeline, I'd expect to get back 1 and 2 from the above list. I get back 1 and 3 instead!!!! How?

This causes further weirdness down the line; if I use skip/limit to page, some items will appear on multiple pages, causing the clientside object tracker to freak out and crash, but I definitely nailed this sorting anomaly as the root cause of all those problems.

wdberkeley

Let me clear up a couple of misunderstandings that I feel might be lurking based on the comments:

  1. $limit is a pipeline stage that always cuts down the number of documents in the pipeline to at most the specified number. There's nothing tricky about it affecting what is "searched" versus "returned". It's just a pipeline stage that transforms one set of documents into another set by getting rid of all the ones > n in the order the documents are presented to it, when the limit parameter is n. Note that the order might not be very meaningful. We'll talk about the tricky part in a second :D

  2. The result returned by the aggregation query with $limit isn't wrong; it's just different. Both have the same sort key, so you really can't complain if the two pipelines returned 123 and 132, respectively, and then limit 2 gives you 12 and 13, respectively. I understand how, if you went on to use $match, etc. later on on other fields, the results could be surprising, but you can't say that the output is wrong.

As for an explanation of why we see 13 instead of 12, my guess is that it has to do with $sort+$limit coalescence. The limit affects how the sort occurs, effectively making it quit earlier. My guess is that, since it quits earlier, it never considers 2, which, when it is considered without a $limit, is sorted before 3 (they have the same sort key, so it doesn't matter where it's put).

If you post example documents and a complete aggregation pipeline, perhaps there's more that could be said to help you, but this is my guess based on what I see.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

mongodb: $sort and $limit behaves weird with undefined

From Dev

MongoDB .limit() ignoring .sort()?

From Dev

MongoDB .limit() ignoring .sort()?

From Dev

mongodb 'sort' not working if 'limit' is removed

From Dev

limit() and sort() order pymongo and mongodb

From Dev

Mongodb aggregate distinct with sort and limit

From Dev

set erase behaves weird

From Dev

GlassPane behaves weird

From Dev

Labels alignment behaves weird

From Dev

GlassPane behaves weird

From Dev

Bash time behaves weird

From Dev

maximum limit for MongoDB 2.6 sort query

From Dev

Mongodb aggregate sort and limit within group

From Dev

MongoDB: sort and limit query with 'or' operator on embedded documents

From Dev

limit and sort each group by in mongoDB using aggregation

From Dev

Problem with 'Sort exceeded memory limit' MongoDb in Spring

From Dev

mongodb sort with skip and limit not sort the record according to index

From Dev

mongodb sort with skip and limit not sort the record according to index

From Dev

Object literals behaves weird in the console

From Dev

re.findall behaves weird

From Dev

Spring @Transactional annotation behaves weird

From Dev

OneToOne's mappedBy behaves weird

From Dev

MongoDB Calculate Values from Two Arrays, Sort and Limit

From Dev

|MongoDB| How to sort and limit embedded arrays? embedded array pagination

From Dev

MongoDB 2.6 Index set up, query using $or, $in, with limit and sort

From Dev

sort behaves weirdly with scientific notation

From Dev

generics behaves weird with inner class with instanceOf check

From Dev

Why does the Numpy Diag function behaves weird?

From Dev

UISegmentedControl behaves in a weird way on UITableView Header

Related Related

HotTag

Archive