0

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

Iano
  • 30
  • 4

1 Answers1

0

{'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 ) ));
}
user602525
  • 3,126
  • 4
  • 25
  • 40
  • I'm having more trouble with the functional part. In the example, there is never a notion of parent_id, this is a typo I think. also if I understand it correctly, parent.pop('parent') leaves parent as an array with the keys name, slug and ancestors. Isn't the ancestors key here suppose to be _id? – Iano Dec 16 '13 at 00:55
  • The part of your example I get :) – Iano Dec 16 '13 at 01:00
  • parent is a dictionary in python, so parent.pop('parent') will remove parent key from the dictionary and return the value. – user602525 Dec 16 '13 at 01:02
  • After reviewing the document a couple of times, I have also concluded that the parent_id in question is a typo – user602525 Dec 16 '13 at 01:03
  • So the dictionary that is kept has as keys the 3 I mention in my comment, correct? – Iano Dec 16 '13 at 01:04
  • Yes, do you want me to do the 2nd question in PHP? – user602525 Dec 16 '13 at 01:05
  • That might help, ty mate :) – Iano Dec 16 '13 at 01:18
  • That's exactly what I have in my code. I really think there's a logical error in the example code the MongoDB site provided. Can you confirm that 'ancestors' needs to be '_id' as fields returned in while loop? – Iano Dec 16 '13 at 01:39
  • It's working now, what took me of my game the most were the two errors in the examples. Really like to thank you the time you took to assist me! – Iano Dec 16 '13 at 01:46