0

I have created a "params" collection in Mongo with the following structure:

{
    "_id" : "id1",
    "list" : [
        {
            "type" : "type1",
            "subtypes" : [ "id1 subtype11", "id1 subtype12" ]
        }
        {
            "type" : "type2",
            "subtypes" : [ "id1 subtype21", "id1 subtype22" ]
        }
    ]
}
{
    "_id" : "id2",
    "list" : [
        {
            "type" : "type1",
            "subtypes" : [ "id2 subtype11", "id2 subtype12" ]
        }
        {
            "type" : "type2",
            "subtypes" : [ "id2 subtype21", "id2 subtype22" ]
        }
    ]
}

I want to get all "subtypes" for "_id":"id1" and "type":"type1". I found out that the way to do this in the Mongo shell is

db.params.find (
    { $and: [
        {"_id" : "id1"},
        {"list.type" : "type1"}
    ] }
)

I have two questions:

  1. Am I using $and (read: "am I creating the query") the correct way?
  2. How to parse this query to PHP code properly? I get lost with the syntax :(.

Thank you!

jfabian
  • 19
  • 1
  • 5
  • 1. No, you can remove the $and it is not needed, 2. What do you mean? – Sammaye Jun 13 '13 at 14:08
  • Thanks for the hint, although wouldn't I receive the second record as well, since it also has an element `"type":"type1"` in the array `"list"`? Also, I figured out that I should first get the complete record for `"_id":"id1" before doing anything else in my PHP code, so the whole process should become simpler. Thanks! – jfabian Jun 13 '13 at 15:03
  • No you wouldn't, it isn't an $or operator between object properties in a query but $and by default, and also the explicit $and operator acts slightly differently with indexes so it is better to use no operator there. – Sammaye Jun 13 '13 at 15:05
  • Oh! Sorry, I hadn't understood correctly what you wrote, now I got it. Just one more question, by the way: What if I want to create an array with the values of the `type` fields, so if I want to search for `"_id":"id1"`, I get `["type1", "type2"]`? Is it possible to do that (I am guessing the aggregation framework is needed)? Thanks! – jfabian Jun 13 '13 at 15:57
  • With your current structure you would need the aggregation framework using $unwind however, this is probably something better done in PHP if I am honest – Sammaye Jun 13 '13 at 16:50

2 Answers2

1

It turns out that the PHP code that answers this question was not that difficult, actually:

$query = array('_id' => 'id1', 'list.type' => 'type1');
$result = $collection->find($query);

/* Use this to access each element of the results */
foreach($result as $doc) {
    /* Code goes here */
}

If one wants to use each value in "type" instead (and print them all for example), the code would be:

$output = [];
$query = array('_id' => 'id1');
$field = array('list.type' => true);

$result = $collection->find($query, $field);
foreach($result as $doc) {
    foreach($doc['list'] as $elem) {
        $output[] = $elem['type'];
    }
}

I found out all of this by using the var_dump() function on each document and analyzing the output. Hope this helps beginners like me. Thanks to Sammaye for the tips! :)

jfabian
  • 19
  • 1
  • 5
1

$collection->find(array(), array('USERS.TASKS.MISSION_SAS_ID' => true));

use this above code to get sub document data

Shiv Kumar Sah
  • 1,129
  • 1
  • 13
  • 17