2

This question doesn't necessarily have to be related to PHP or MongoDB.

I have MongoDB database with categories collection. Documents inside collection looks like below

{
title : 'Parent 1',
cat_id : '_ABC1',
level : 1
}
{
title : 'Parent 2',
cat_id : '_ABC2'
level : 1
}
{
title : 'Child 1',
cat_id : '_ABC1_CEF1'
level : 2
}
{
title : 'Child 2',
cat_id : '_ABC1_CEF2'
level : 2
}
{
title : 'Child Child 1',
cat_id : '_ABC1_CEF1_GHI1'
level : 3
}
{
title : 'Child Child 2',
cat_id : '_ABC1_CEF1_GHI2'
level : 3
}

Nesting Now, what I want to do in PHP is get nested array(s) like

$array = array(
    array(
       'title' => 'Parent 1',
       'cat_id' => '_ABC1',
       'sub' => array(
          'title' => 'Child 1',
          'cat_id' => '_ABC1_CEF1',
          'sub' => array(
              array(
                 'title' => 'Child Child 1',
                 'cat_id' => '_ABC1_CEF1_GHI1'
              ),
              array(
                 'title' => 'Child Child 2',
                 'cat_id' => '_ABC1_CEF1_GHI2'
              )
          )
        )
    ),
    ...
    ...
)

For that I am using following algorithm (fetch nested level = N) (N is a fetching parameter number that tells iterator, how deep array has to be fetched)

$array_holder = array();

foreach(MongoGetLevel1Cats as $parent){
  $parent['sub'] = array();

   foreach(MongoGetLevel2Cats as $child){
      $child['sub'] = array();

      foreach(MongoGetLevel3Cats as $child_child){
          $child_child['sub'] = array();

          ...
          ...

          array_push($child['sub'], $child_child);
        }

      array_push($parent['sub'], $child);
    }

  array_push($array_holder, $parent);
}

Return $array_holder;

As this function will give me the desired result but I don't have control over the deep nested level. If have to fetch nested level of order 100, I have to write foreach loop insider foreach loop for 100 times. Also I don't know performance wise this strategy will be good or not.

Does anybody have any idea how we solve this more strategically? Perhaps with for & foreach loop in combination which doesn't involve nesting foreach loop?

  • Im unfamiliar with MongoDB behaviour, but doesnt it return an array if you query it? – DevDonkey Apr 23 '16 at 11:14
  • I have edited my answer, I believe it will do the job well for you here. – Webeng Apr 23 '16 at 11:32
  • Do you really have to build the tree yourself? If you had had one document for single parent, you would be able to fetch the nested structure right from MongoDB. – Ruslan Osmanov Apr 23 '16 at 11:54
  • @RuslanOsmanov http://stackoverflow.com/a/14855633/6244116 , yeah but mongodb doesn't support $ operater after two levels. So, it would be a headache to update nested data. – Uday Hiwarale Apr 23 '16 at 12:07

1 Answers1

0

You can use a callback function. For example:

function add_two($result, $how_many_times)
{
  $result = $result + 2;//adds 2
  echo "current =".$result."<br>";
  $how_many_times--;
  if ($how_many_times>0)
  {
    $result = add_two($result, $n);
  }
  return $result;
}

$resultVar = add_two(5, 5);//should give 15...

echo "resultvar = ".$resultVar."<br>";//outputs: resultvar = 15

In the previous example, I am placing the same function add_two() inside itself and have created a conditional that sees how many iterations I want. Every time I iterate once, I subtract 1 value from $how_many_times. Once $how_man_times == 0, the add_two() function will no longer be called, and the result will have been obtained.

Similarly you can do the same thing with your code. There is no reason for you to have to rewrite the same function all over again if you can just call it inside itself.

Let me know if this is what you were looking for :)

Webeng
  • 7,050
  • 4
  • 31
  • 59