0

我想创建一个多维集合。该集合具有位置。每个位置都有用户,每个用户都有照片。

现在该系列有位置,例如

{ "_id" : ObjectId( "52148266c36b4403e855bef9" ),
  "latitude" : 48.958,
  "id" : "110600715",
  "longitude" : 9.13,
  "name" : "Coffee" }

我的最终结果需要是这样的:

{ "_id" : ObjectId( "52148266c36b4403e855bef9" ),
  "latitude" : 48.958,
  "id" : "110600715",
  "longitude" : 9.13,
  "name" : "Coffee", 
  'users' : [
        {
        'user' : 45,
        'username' : 'Me',
        'user_fullname': 'Name Lastname',
        'photos': [
            {
            'photo_id' : 10,
            'created_time' : 1236456712,
            'link' : 'http...',
            'image' : 'http...',
            'tags' : 'a'
            },
            {...}
            ] # end of photos list
        },
        {...}
        ] #end of users list
}

如果用户不存在,则创建新用户并添加第一张图片。如果用户存在,则添加具有唯一性的下一张图片photo_id

这是我尝试以下的示例。我正在将pymongo与 python 一起使用。我知道我错过了第二个$addToSet或类似的东西。

db.col.update( {'_id':location_id['_id']},
            { '$addToSet' : 
                { 
                'user' : int(i['user']['id']),
                'username' : i['user']['username'],
                'user_fullname': i['user']['full_name'],
                'photos':
                    {
                    'photo_id' : i['id'],                                   
                    'created_time' : int(i['created_time']),
                    'link' : i['link'],
                    'image' : i['images']['url'],
                    'tags' : i['tags']
                    }
                }
            }
        )
4

1 回答 1

0

您不能在单个操作中执行此操作 - 您可以进行更新并检查它更新了多少。

在这里,我们使用默认的写入关注点(来自 MongoClient),例如:w:1我们首先查询并期望该位置存在用户:

result = db.col.update(
            {'_id':location_id['_id'], "users": {"$elemMatch": {'user' : int(i['user']['id'])}}}, 
            {'$addToSet': {"photos": {'photo_id' : i['id'],                                   
                                  'created_time' : int(i['created_time']),
                                  'link' : i['link'],
                                  'image' : i['images']['url'],
                                  'tags' : i['tags']}}});

如果结果 ['n'] 等于 0,则表示我们不匹配,并且i[user]该位置没有用户。所以我们也可以使用$addToSet

if result['n'] == 0:
   db.col.update({'_id':location_id['_id']},
        { '$addToSet' : 
            { 
            'user' : int(i['user']['id']),
            'username' : i['user']['username'],
            'user_fullname': i['user']['full_name'],
            'photos':
                [{'photo_id' : i['id'],                                   
                  'created_time' : int(i['created_time']),
                  'link' : i['link'],
                  'image' : i['images']['url'],
                  'tags' : i['tags']
                }]
            }
        });

注意

由于我们正在执行两项操作 - 理论上存在竞争条件,这可能意味着第二次更新不会更新任何内容,因为其他一些线程已将用户添加到该位置。如果您想确保它确实更新,您应该仔细检查第二个更新结果,然后可能会循环回来。这取决于这种竞争条件的真实程度。

于 2013-08-21T13:59:58.003 回答