查询后更新嵌套值

时间:2020-12-28 23:09:32

标签: python mongodb pymongo

我在 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'
}

我的目标是:

  1. 在“api_processed”=false 的所有对象中查找所有“eroded_sample_b64”
  2. 做一些处理
  3. 在相同的嵌套“框架”结构中插入结果
  4. 更新“api_processed”= true

我想反对这样的事情:

{
_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'
        },
    {

我尝试过以下代码:

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" }
                 }}
             )

但不幸的是我得到了错误的结果,因为“结果”键没有嵌套在正确的“框架”中:

{
    _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'
}

我真的不明白我做错了什么。 任何帮助/评论将不胜感激。 非常感谢

1 个答案:

答案 0 :(得分:1)

在您的更新中,您需要使用 $ positional operator

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