Home > Mobile >  MongoDB: how to get and remove the first value from an array? And how to get and remove the last?
MongoDB: how to get and remove the first value from an array? And how to get and remove the last?

Time:10-20

So, for example, if I had the document:

{
   _id: 1,
   items: ["aaa", "bbb", "ccc", "ddd", "eee"]
}

Let's say I want the first element, then I would of course get "aaa" returned and the updated document would be:

{
   _id: 1,
   items: ["bbb", "ccc", "ddd", "eee"]
}

I realise there is $pop which will remove either the first or last element respectively, depending on whether a parameter of -1 or 1 is used, but I haven't figured out a way of actually having this value returned

Likewise, I would also be looking for a way to pop the last element and have its value returned

I would want to be able to do this with a single command/no kind of concurrency issues...i.e. I wouldn't want 1 command to get the first element, then another command to remove the first element, since another instance could get the same value, before the original instance had removed it

Also, does anyone know if there is a difference in performance between deleting the first element or the last? Since, in many (all?) programming languages, removing the first element from an array is O(n), while removing the last element should be O(1)...so I wonder if 'popping' the first element from a Mongo array would be slower than popping the last?

CodePudding user response:

Check this out

// select some random mongo database for testing
use("stack")

// at first, clean collection
db.data.drop()

// populate with initial data
db.data.insertMany([
{
   _id: 1,
   items: ["aaa", "bbb", "ccc", "ddd", "eee"]
}
])

// which element do we want to remove, first or last
first_or_last = "first"

db.data.findOneAndUpdate(
    // match filter | in real case we should also have array length stored
    {_id: 1},
    // update query
    { $pop: {"items": {"last": 1, "first": -1}[first_or_last] } },

    // options
    {  // return popped array element | use $last if in $pop value is 1, $first otherwise
        projection: {popped_element: {[`\$${first_or_last}`]: "$items"}, _id: 0},
    }
)

// db.data.find()

Result after removing "first" element

{
  "popped_element": "aaa"
}

After running .find()

[
  {
    "_id": 1,
    "items": [
      "bbb",
      "ccc",
      "ddd",
      "eee"
    ]
  }
]

  • Related