0

I have the next document in MongoDB:

Contest document:

{
 "_id": ObjectId("502aa915f50138d76d11112f7"),
 "contestname": "Contest1",  
 "description": "java programming contest", 
 "numteams": NumberInt(2),
 "teams": [
   {
    "teamname": "superstars",
    "userid1": "50247314f501384b011019bc",
    "userid2": "50293cf9f50138446411001c",
    "userid3": "50293cdff501384464110018"
   },

   {
    "teamname": "faculty",
    "userid1": "50247314f501384b0110100c",
    "userid2": "50293cf9f50138446410001b",
    "userid3": "50293cdff501384464000019"
   }
 ],
 "term": "Fall 2012"
}

Imagine that I have more than this document where users can register. I want to find all the contest that a user has registered. I have something like this so far:

$id = "50247314f501384b011019bc";
$user = array('userid1' => $id, 'userid2' => $id, 'userid3' => $id );
$team = array('teams' => $user);            
$result =$this->collection->find($team);
return $result;

Could somebody help me with that?

Thank you.

------Solved------

$team = array('$or' => array(array('teams.userid1' => $id),
               array('teams.userid2' => $id), 
               array('teams.userid3' => $id)
                 ));            

$result =$this->collection->find($team);

1 Answer 1

3

Your data structure is awkward to query because you have an array of embedded documents. With a slight change to the data you could make this easier to work with.

I've put the user IDs into an array:

{
 "contestname": "Contest1",  
 "description": "java programming contest", 
 "numteams": 2,
 "teams": [
   {
    "teamname": "superstars",
    "members": [
        "50247314f501384b011019bc",
        "50293cf9f50138446411001c",
        "50293cdff501384464110018"
    ]
   },

   {
    "teamname": "faculty",
    "members": [
        "50247314f501384b0110100c",
        "50293cf9f50138446410001b",
        "50293cdff501384464000019"
    ]
   }
 ],
 "term": "Fall 2012"
}

You could then do the PHP equivalent find() for:

db.contest.find(
        {'teams.members':'50247314f501384b011019bc'},
        {'contestname':1, 'description':1}
    )

Which would return the matching contests this user had entered:

{
    "_id" : ObjectId("502c108dcbfbffa8b2ead5d2"),
    "contestname" : "Contest1",
    "description" : "java programming contest"
}
{
    "_id" : ObjectId("502c10a1cbfbffa8b2ead5d4"),
    "contestname" : "Contest3",
    "description" : "Grovy programming contest"
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I solved it with my current structure. Your dot notation was useful though.
@antoniomtz: Glad you found a solution! A potential issue with your current schema is that you will need to list all the fields in your $or .. so this may be inconvenient/inefficient unless you have a limited number of members per team. If you can rework that into an array you could take advantage of indexes as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.