0

$setなどの条件を使用してより高度な更新を行う方法があるかどうかを調べようとしています。これは私が擬似コードでやろうとしていることです:

# new data to use in a possible update
newData = { 'emailAddress' : $usersEmailAddress,
            'keyA' : 'valueA', 
            'keyB' : None,
            'keyC' : '<null>' }

self.request.root.db.users.update(
                { 'emailAddress' : newData['emailAddress'] },
                { '$set': { 
                          "Here, loop through all newData keys/values and if 
                          notNull(newData[key]) == True and is different than the 
                          corresponding key/value in the user 
                          document (or if user document doesn't have that key) 
                          than update with newData key/value"
                          } }, upsert = False, safe = True )

# The result should be that if the value of keyA (and ONLY key A because the 
#  others are null) is different in the user document
#  than in newData, than the user document should be updated with the new value.



# function to catch any possible None value or equivalent string
def notNull(valueToCheck):
    if thingToCheck and thingToCheck != "null" and thingToCheck != 'nil' and thingToCheck != '<null>' and thingToCheck != '' and thingToCheck != ' ':
        return True
    else:
        return False

これを行う最も効率的な方法は何ですか?現在、find_oneを使用してドキュメント全体をプルする必要があるため、かなりコストがかかると言われています。$ setだけでこれを行う方法はありますか?

4

1 に答える 1

0

いいえ、MongoDBはこの機能をサポートしていません。あなたが言うように、ドキュメントを取得し、クライアント側のコードで分析し、その内容に基づいて更新を発行するか、次のような一連の更新を発行することができます。

db.users.update({
    'emailAddress': newData['emailAddress'],
    '$or': [
        { 'keyA': { '$exists': false } },
        { 'keyA': None } ] }
    ]
}, {
    '$set': { 'keyA': newData['keyA'] }
})

もちろん、前者は単一のフェッチと単一の更新であるため、より効率的です。ただし、同じドキュメントを同時にフェッチおよび更新する複数のMongoDBクライアントを防ぐ必要があるかどうかを検討してください。

于 2012-08-21T20:34:29.673 に答える