Question

I'm a PHP developer trying to tackle http://docs.mongodb.org/ecosystem/use-cases/category-hierarchy/, but I don't know much about Python.

My first question:

for cat in db.categories.find(
{'ancestors._id': bop_id},
{'parent_id': 1}):
build_ancestors_full(cat['_id'], cat['parent_id'])

Where does 'parent_id' come from? Isn't it suppose to be just 'parent'?

My second question:

def build_ancestors_full(_id, parent_id):
ancestors = []
while parent_id is not None:
    parent = db.categories.find_one(
        {'_id': parent_id},
        {'parent': 1, 'name': 1, 'slug': 1, 'ancestors':1})
    parent_id = parent.pop('parent')
    ancestors.append(parent)
db.categories.update(
    {'_id': _id},
    {'$set': { 'ancestors': ancestors } })

I would appreciate a psuedo explanation (or PHP equivalent) of this helper function, mainly the following lines:

parent_id = parent.pop('parent')
ancestors.append(parent)

Thank you!

UPDATE & Answer:

Two errors in the example codes:

The first is 'parent_id' => should be 'parent'

The second is

{'parent': 1, 'name': 1, 'slug': 1, 'ancestors':1})

=> ancestors field should be _id

Was it helpful?

Solution

{'parent_id': 1} in the find query is saying that you only want to return the key parent_id, think of it like ( and it can be used like ) {'parent_id': true} try it out in the mongo shell. This parameter is called the projection, you can suppress keys as well. But in this instance it is saying, only return to me the 'parent_id' key from the document that is found. However, if you do not suppress the _id column explicitly, it WILL be returned.

The second part of your question: This code is assigning the value that is returned from the find query, in this case it will be a document where the _id is equal to the parent_id passed into the function - build_ancestors_full. This document will display the parent key, name key, slut, and ancestors key. parent.pop('parent') will pop a value from the 'parent' key of the parent variable which holds the document I just described. Ancestors is an array, ancestors.append(parent) will append the document I described above to the ancestors array.

PHP Equivalent:

// get all documents that contain ancestors._id = $bop_id, only return the 'parent_id' field
$result = $db->categories->find(array('ancestors._id' => $bop_id), array('parent_id' => 1));

foreach ($result as $document) {
    build_ancestors_full($document['_id'], $document['parent_id']);
}

From your first question - I agree that the use of parent_id is a typo.

Part 2 PHP:

function build_ancestors_full($id, $parent_id) {
    $ancestors = array();
    while ($parent_id != null) {
        $parent = $db->categories->find_one(
            array('_id' => parent_id),
            array('parent' => 1, 'name' => 1, 'slug' => 1, 'ancestors' => 1));
        $parent_id = $parent['parent'];
        unset($parent['parent']);
        // array push
        $ancestors[] = $parent;
    } 
    $result = $db->categories->update(
        array('_id' => _id),
        array('$set' =>  array('ancestors' => $ancestors ) ));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top