0

Now, I have a document in my collection that I would like to delete on click, and those are comments inside the post document.

Here's the structure:

{
    "_id" : "design-patterns-vs-frameworks",
    "title" : "Design Patterns vs Frameworks",
    "category" : [ 
        "Frameworks", 
        " Design Patterns", 
        " PHP"
    ],
    "date_time" : ISODate("2014-09-02T13:45:29.124Z"),
    "description" : "Frameworks vs Design Patterns",
    "content" : " Content!",
    "author" : "Maciej Sitko",
    "comments" : [ 
        {
            "_id" : ObjectId("54061528af105b51133c986c"),
            "comment" : "ashfklsfsl\r\n",
            "author" : "maciejsitko",
            "date" : ISODate("2014-09-02T19:06:16.646Z")
        }, 
        {
            "_id" : ObjectId("5406152caf105b51133c986d"),
            "comment" : "lfasdlfsfl",
            "author" : "maciejsitko",
            "date" : ISODate("2014-09-02T19:06:20.652Z")
        }
    ]
}

The full delete link is:

delete.php?post=css-clearfix-explained&id=540617e3af105b8d133c986a (as you see two get variables 'post' and 'id')

I tried several solutions,

-First one:

$collection->update( array("_id" => $_GET['post']), array( '$unset' => 
 array("comments" => array("_id" => $_GET['id']))) );

This one just removed all of my comments inside the comments array.

-Second:

$delete = array('$pull' => array("comments" => array( '_id' => $_GET['id'])));
$collection->update(array('_id' => $_GET['post']), $delete);

Did not pretty much do anything, strangely enough, this should work, right?

-Third solution:

$collection->remove( array('_id' => $_GET['post'], 'comments._id' => $_GET['id']));

What would be the proper way of achieving this? I struggled on this one a lot, even implementing some aggregation query and it didn't work out.

1
  • How To add _id To emboded document (comments) in php Commented Apr 18, 2018 at 9:15

1 Answer 1

4

To remove an element from an array you use the $pull operator. This takes a "query" expression to identify the element you wish to remove:

$collection->update( 
    array("_id" => $_GET['post']),
    array( '$pull' => 
        array(
            "comments" => array(
                "_id" => new MongoId( $_GET['id'] )
            )
        )
    )
);

The "query" portion of $pull acts on the individual elements of the array specified, so anything matching the condition will be removed from the array. But also importantly your request parameter is a "string" so you need to cast this as an actual ObjectId value which you can cast in PHP with the MongoId class from the driver.

NOTE Modern driver releases use MongoDB\BSON\ObjectId as the correct method for casting "string hex value" into an actual ObjectId representation.

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

1 Comment

Thank you, I tried the solution you listed above several times, but forgot to put a new MongoId() indicator, instead, I was just putting there $_GET['id'] in a raw fashion, so it did not pull anything out of the array. Cheers!

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.