phpmongodblaravelmoloquent

Search through embedded collections in MongoDB


I'm currently working on a PHP (laravel) project where we're using MongoDB (the jenssegers package). I made password resets up on the following structure:

{
    "_id" : ObjectId("58d56135b462e816642abbd1"),
    "email" : "wesley@foo.bar",
    "updated_at" : ISODate("2017-03-26T20:46:14.074Z"),
    "created_at" : ISODate("2017-03-24T18:11:01.040Z"),
    "passwordReset" : [ 
        {
            "token" : "59b4b694e9ddcd9b44b0374eac595b28",
            "updated_at" : ISODate("2017-03-24T18:11:05.017Z"),
            "created_at" : ISODate("2017-03-24T18:11:05.017Z"),
            "_id" : ObjectId("58d56139b462e816642abbd4")
        }
    ]
}

However, multiple users can have multiple passwordReset's. So, when I want to search for tokens, I'd like to just be able to search through all resets instead of doing this:

    $users = User::all();
    $activeReset = null;
    foreach ($users as $user) {
        if (! is_null($user->passwordReset)) {
            foreach ($user->passwordReset as $reset) {
                if ($reset->token == $this->route('token')) {
                    $activeReset = $reset;
                }
            }
        }
    }

It's a working solution, but it's not the prettiest, also, when the app goes into production, this will cause huge load times, which is not what I'm looking for.

However, just getting all resets through PasswordReset::all(); results in an empty array.

So, is there a way to do this, without going through all users? Through Laravel itself or maybe through "raw" PHP?

Thanks.


Solution

  • You can get all users who have at least 1 matching token, if you are using EmbedsMany relation :

    User::where('passwordReset', 'elemMatch', array('token' => $this->route('token')));