3

I've been trying to remove the final element of an array in a MongoID document, but I am struggling for some unknown reason.

We have a document in MongoDB:

{
    "_id" : ObjectId("606c774ff34c295ec7ac5eb7"),
    "child_table" : [ 
        {
            "_id" : ObjectId("606c7768f34c291171ac5ec2"),
            "string3" : "y"
        },
        {
            "_id" : ObjectId("606c7768f34c291171ac5ef6"),
            "string3" : "u"
        }
    ]
}

This document is contained within record.

record = Record.find_by(:id=> "606c774ff34c295ec7ac5eb7")

I can delete the second element, which I'm doing with:

record.child_table.delete_at(record.child_table.count-1)

This works fine, the second element of the array child_table is deleted. All right. However, when I go to delete the final element in the array, the code runs with no errors, but I go to check the document in Mongo and it is still showing the final element.

I have also tried running:

self.unset(:child_table)

But this has not done anything for me.

Please let me know any suggestions! Thanks

Daniel Lawton
  • 416
  • 3
  • 9
  • 30
  • Remove unnecessary fields from your data then add a runnable code snippet containing both the insertion and the removal that you are having trouble with. – D. SM Apr 06 '21 at 17:57
  • @D.SM I've removed unnecessary fields from the data. It is only the removal I'm having trouble with. The runnable code snippet is a one liner, which is in the original question. As stated, that line of code works when the array contains more than 1 element. – Daniel Lawton Apr 07 '21 at 09:45
  • I don't see any runnable code in your question. "Runnable" means by someone other than you who doesn't have the rest of your application on their computer. – D. SM Apr 07 '21 at 13:48

2 Answers2

3

Use $pop

The $pop operator removes the first or last element of an array. Pass $pop a value of -1 to remove the first element of an array and 1 to remove the last element in an array.

Demo with only 1 child element - https://mongoplayground.net/p/eGLqEPUjUAV

Demo with 2 child elements - https://mongoplayground.net/p/nxXBaqK-3RL

db.collection.update(
    { _id: ObjectId("606c774ff34c295ec7ac5eb7") },
    { $pop: { child_table: 1 } } // removes last element from the array
)
Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
  • Thank you for the answer, I'm wondering now, why is it that the methods I'm trying above don't work? Is it possible to clear the array without using MongoID methods, and then save the model? – Daniel Lawton Apr 19 '21 at 10:22
1

please refer to https://stackoverflow.com/a/4588909/6462538

trick here is to first unset last element in array and then pull that element. Considering our collection is users below commands will remove the last element of array

var record= db.users.find({ _id: ObjectId("606c774ff34c295ec7ac5eb7") }).toArray();

var index= record[0].child_table.length-1;
var unsetelement = "child_table."+index;
unsetelement = unsetelement.toString();

db.users.update({ _id: ObjectId("606c774ff34c295ec7ac5eb7") }, {$unset : { unsetelement : 1 }}) 
db.users.update({ _id: ObjectId("606c774ff34c295ec7ac5eb7") }, {$pull : {"child_table" : null}})
  • Thank you for this, however I am curious, is it simply not possible to do without running MongoID commands? For instance, when I do simply ```record.child_table.delete_at(0)``` I can see that the array is cleared when in a binding, however then executing ```record.save``` I can see in MongoDB that the array still contains the final element. – Daniel Lawton Apr 12 '21 at 10:14
  • I would really appreciate it if you could take a look at my previous comment. – Daniel Lawton Apr 13 '21 at 10:32
  • @DanielLawton you can't update a DB without sending commands to the DB. – Tom Slabbaert Apr 13 '21 at 17:33
  • @TomSlabbaert I understand that but what I'm not understanding is why doing ```record.child_table.delete_at(0)``` followed by ```record.save``` does not remove the final element in the array. I can put a binding in the code after the ```delete_at``` and can see that the array is empty. After running ```record.save``` the array is still the same in Mongo – Daniel Lawton Apr 15 '21 at 10:24