user3925023
user3925023

Reputation: 687

Update a nested value after query

I have following data structure in Mongo:

{
    _id: ObjectId('5fea5c2dcfe3920cdbe10313'),
    video_path: '/media/out_.mp4',
    frame_skip: '100',
    frame_c: '20',
    api_processed: false,
    samples: [
        {
            frame: 301,
            eroded_hu_moments: [
                [
                    0.002703944102615306
                ]
            ],
            eroded_sample_b64: '/9j/4AAQSkZJRgABA...',
            eroded_sample_inverted_b64: '/9j/4AAQSkZJRgABAQAA...'
            },
        {
            frame: 302,
            eroded_hu_moments: [
                [
                    0.002703944102615306
                ]
            ],
            eroded_sample_b64: '/9j/4AAQSkZJRgABAQAAAQABAAD/...',
            eroded_sample_inverted_b64: '/9j/4AAQSkZJRgABAQAAAQABAAD...'
            },
        {
            frame: 303,
            eroded_hu_moments: [
                [
                    0.002703944102615306
                ]
            ],
            eroded_sample_b64: '/9j/4AAQSkZJRgABAQAAAQA....',
            eroded_sample_inverted_b64: '/9j/4AAQSkZJRgABAQAAAQA....'
            }
    ],
    TOT_execution_time: '0:00:07.215424'
}

My goal is to:

  1. Find all the "eroded_sample_b64" in all objects where "api_processed"=false
  2. Do some processing
  3. Insert in the same nested "frame" structure the results
  4. update "api_processed" = true

I'd like to object something like this:

{
_id: ObjectId('5fea5c2dcfe3920cdbe10313'),
video_path: '/media/out_.mp4',
frame_skip: '100',
frame_c: '20',
api_processed: true,
samples: [
    {
        frame: 301,
        eroded_hu_moments: [
            [
                0.002703944102615306
            ]
        ],
        eroded_sample_b64: '/9j/4AAQSkZJRgABA...',
        eroded_sample_inverted_b64: '/9j/4AAQSkZJRgABAQAA...'
        results: 'test_OK'
        },
    {

I've tryed with following code:

client = MongoClient("mongodb://root:example@localhost:27017/")
mydb = client["image"]
mycol = mydb["samples"]

mydoc = mycol.find( { "api_processed": False},
{ "_id": 1,"samples.eroded_sample_inverted_b64": 1, "samples.frame": 1}
)
url = 'http://localhost:8000/prediction/'
for x in mydoc:
  for sample in x.get('samples', []):
    ##SOME PROCESSING
    
    ###SET
    doc = mycol.update_one(
             {"_id": x['_id'], "samples.frame": sample['frame']},
             {"$set": {
                 "api_processed": true,
                 "samples": { "results": "some test res" }
                 }}
             )

But unfortunately i obtain wrong results, as "results" key is not nested in the right "frame":

{
    _id: ObjectId('5fea5c2dcfe3920cdbe10313'),
    video_path: '/media/out_.mp4',
    frame_skip: '100',
    frame_c: '20',
    api_processed: false,
    samples: [
        {
            frame: 301,
            eroded_hu_moments: [
                [
                    0.002703944102615306
                ]
            ],
            eroded_sample_b64: '/9j/4AAQSkZJRgABA...',
            eroded_sample_inverted_b64: '/9j/4AAQSkZJRgABAQAA...'
            },
        {
            frame: 302,
            eroded_hu_moments: [
                [
                    0.002703944102615306
                ]
            ],
            eroded_sample_b64: '/9j/4AAQSkZJRgABAQAAAQABAAD/...',
            eroded_sample_inverted_b64: '/9j/4AAQSkZJRgABAQAAAQABAAD...'
            },
        {
            frame: 303,
            eroded_hu_moments: [
                [
                    0.002703944102615306
                ]
            ],
            eroded_sample_b64: '/9j/4AAQSkZJRgABAQAAAQA....',
            eroded_sample_inverted_b64: '/9j/4AAQSkZJRgABAQAAAQA....'
            },
        {
            results: 'test_OK'
        }
    ],
    TOT_execution_time: '0:00:07.215424'
}

I don't really understand what I'm doing wrong. Any help/comments will be really appreciated. Many thanks

Upvotes: 1

Views: 40

Answers (1)

Belly Buster
Belly Buster

Reputation: 8814

In your update you need to use the $ positional operator.

    doc = mycol.update_one(
        {"_id": x['_id'], "samples.frame": sample['frame']},
        {"$set": {
            "api_processed": True,
            "samples.$.results": "some test res"
        }}
    )

Upvotes: 1

Related Questions