1

I have stored a document set in MongoDB like below where ID is generated automatically through PHP

{
"_id": {
    "$oid": "5ff745237d1b0000860007a6"
},
"user": "5ff741fb7d1b0000860007a4",
"name": "Test",
"slug": "fed73b70d080584c21e0a4353825ef91",
"category": "5fef4a467d1b000086000745",
"images": [{
    "100x128": "test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg",
    "200x256": "test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg",
    "300x385": "test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg",
    "500x642": "test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg"
},
{
    "100x128": "test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg",
    "200x256": "test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg",
    "300x385": "test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg",
    "500x642": "test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg"
}],
}

Now the problem is I want to get value from images object from key 100x128 only from the first array.

I am using the below code to achieve

$productsArray = $collection->aggregate(
    [
        [
            '$match' => [
                                    'user_id' => $user_id
                                ]
        ],
        [ '$unwind' => '$images' ],
        [ '$unwind' => '$images.100x128' ],
        [
            '$project' =>   [
                                        'name' => 1,
                                        'image' => '$images'
                                    ]
        ]
    ]
 );

and I always get an output as below

MongoDB\Model\BSONDocument Object
(
   [storage:ArrayObject:private] => Array
    (
        [_id] => MongoDB\BSON\ObjectId Object
            (
                [oid] => 5ff745357d1b0000860007a7
            )

        [name] => Test 1
        [image] => MongoDB\Model\BSONDocument Object
            (
                [storage:ArrayObject:private] => Array
                    (
                        [100x128] => test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg
                        [200x256] => test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg
                        [300x385] => test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg
                        [500x642] => test/year/month/image_da4181762396a31ff44f5ddc08ce6186.jpeg
                    )

            )

    )

)

I am not sure how to get just that specific value. Where am i going wrong here?

1 Answer 1

1

As far as i am getting your question it looks like you would need to understand the mongo concept. So you might get an array representation in UI or in PHP but at the end of day it is object.

Look closely the format that you have posted there is no array but multiple {} in that object just like JS so forget about array concept here.

If my understanding is correct this is what you are looking for

$productsArray = $collection->aggregate(
[
    [
        '$match' => [
                       'user_id' => $user_id
                    ]
    ],
    [ '$unwind' => '$images' ],
    [ '$unwind' => '$images.100x128' ],
    [
        '$project' =>   [
                           'name' => 1,
                           'image' => '$images.100x128'
                        ]
    ]
]

);

Whatever you have googled or used it is correct just you need to add the second unwind value i.e $images.100x128 instead of $images in the $project variable.

You can understand this way that $unwind variable uses recursive logic to get output as you want. Like let's say you have an array inside an array first it will get values from internal array then it will come to parent array and then so on. So the last value in $unwind variable should be used.

I am not sure if it will work on multiple objects but as you said you just need the first one. This should do the charm.

Sign up to request clarification or add additional context in comments.

3 Comments

You are brilliant bro. It worked as expected <3 thanks a ton
Glad to hear it but still not sure that it would work on multiple arrays. I'll upvote this question so that if someone has similar problem it can be highlighted.
I'll check and DM you are reply here

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.