简体   繁体   中英

MongoDB updating nested array with sort and slice, doesn't sort desc

I'm trying to push objects to an embedded array and sort by desc while slicing at 5.

This works if I change created to 1, but it's 'ascending'. What happens now, is new objects, don't actually get inserted into the array, if it's has 5.

Any idea how to do this? Thank you!

 db.user.update({_id : user_id},
                { "$push" : { items : { "$each" : [{
                                                          action : 'one',
                                                          status : 'two', 
                                                          value : 'three',
                                                          created: new Date()
                                                        }
                                                      ],
                                              "$sort" : {created: -1},
                                              "$slice" : -5
                                            }

                            }
                }
              , function(err, doc) {

              });

What is happening is that you have asked MongoDB to sort the items in descending order and keep only the last 5; this means that only the 5 smallest items will be kept. But since you are inserting the items in ascending order (because Date() keeps increasing), once you have inserted 5 items you already have the 5 smallest items, so no subsequent ones will be inserted.

As you have noted if you change the sort order to ascending then you will be keeping the 5 largest items; since every new item has a larger Date() than all the previous ones, every new item will initially be among the largest 5 items so will appear in the list.

If you need the 5 largest items sorted in descending order you could use the ascending sort order when you $push the item in order to use $slice to keep the largest 5, and then when you query the data you can reverse the order of the results in the client.

Everything in your code works as expected. And because of this you actually do not see any results.

What your code is doing:

  1. Find the document with _id = user_id
  2. In its key items insert a bunch of objects (it happens that bunch = 1)
  3. then sort that key items in a decreasing order by the field created
  4. and leave only 5 smallest elements.

The problem appears because of the Date() field. Date is increasing all the time. So every new element will not end up in this 5 smallest elements. When you change you created : 1 , you sort by increasing order and your new date surely end up in the 5 elements.

Regarding this:

Any idea how to do this? Thank you!

If you would better describe what you want I hope I will be able to tell you what you can change, because right now your script is doing exactly the right thing. As you mention, you can put created : 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM