2013-02-26 3 views
0

Je met à jour des enregistrements dans ma collection comme ceci:mise à jour Efficacement enregistrements dans MongoDB/pymongo (peut-être en place?)

for document in myDB.find(): 
    if compliesToSomeRule(document): 
     myDB.update({'_id':document['_id']}, {'$set':{'something':'somevalue'}}) 

Est-ce la façon la plus efficace de le faire?

Il semble juste bizarre que je doive définir le premier paramètre de mise à jour en tant que _id du document puisqu'il s'agit de re-interroger l'index?

Existe-t-il un moyen de mettre à jour "en place" pour ainsi dire?

Répondre

0

Vous effectuez la mise à jour en place. Le premier argument à mettre à jour est une clause find, et c'est ainsi qu'il identifie l'enregistrement à mettre à jour.

modifier

Est-ce que la mise en cache de MongoDB poignée? Oui. MongoDB conserve toutes les données récemment utilisées dans la mémoire vive ( ). Si vous avez créé des index pour vos requêtes et que votre jeu de données de travail est en RAM, MongoDB répond à toutes les requêtes de la mémoire.

MongoDB n'implémente pas de cache de requête: MongoDB sert toutes les requêtes directement à partir des index et/ou des fichiers de données. méthode


En outre, votre nom d'utilisateur est génial :)

+0

Mais la clause de découverte doit retrouver un disque ... qui a déjà été trouvé sûrement? Peut-être pas. p.s. - Le meilleur XKCD hein? : D – LittleBobbyTables

+0

Je pense que ce que Ian obtient, c'est que la première partie de l'appel de mise à jour fait la section "compliesToSomeRule". Dans ce cas, il est dit que document._id == expected_id, très basique/simple. Mais vous pourriez faire: myDB.update ({'a': 0}, {'$ set': ....}). Dans ce cas, vous spécifiez que a == 0. Cette mise à jour modifiera tout document où a == 0, elle est identique à votre méthode "compliesToSomeRule". EDIT: Je vais écrire une réponse plus complète ... – ACE

1

La première partie de la commande de mise à jour vous faites est essentiellement ce que vous voulez de la « compliesToSomeRule ». Par exemple, permet de dire que compliesToSomeRule est défini comme suit:

def compliesToSomeResult(doc): 
    if doc['a'] == 0: 
     return True 
    else: 
     return False 

Ensuite, vous pouvez sauter cette série et il suffit de faire

myDB.update({ 'a' : 0 }, {'$set' : { 'x' : 'y' }}) 

Cela applique ensuite votre document de mise à jour (le deuxième) à tous les documents dans votre collection qui ont un champ d'un égal à 0.

un autre exemple: si vous voulez trouver tous les documents où « a »> 0 que vous pourriez faire

myDB.update({ 'a' : { '$gt' : 0 }}, {'$set' : {'x' : 'y'}}) 

La première section de l'appel de mise à jour, la section "requête", indique comment vous spécifiez quels documents reçoivent la mise à jour. La deuxième section définit la mise à jour.

Voici un document que vous trouverez peut-être utile tout en examinant ce matériel: http://docs.mongodb.org/manual/applications/update/

+0

C'est une bonne idée. Mais habituellement, ma fonction compilesToSomeRule est très complexe et serait probablement assez difficile à implémenter dans le cadre de l'argument finder:/ – LittleBobbyTables

+0

Ahh, cela rend les choses plus difficiles, peut-être si vous mettez un exemple de fonction qui décrit ce que vous voulez faire. capable de trouver une bonne solution. Cela étant dit, je conseille souvent aux gens de faire des opérations complexes comme vous le décrivez du côté des clients, alors peut-être que votre solution originale (celle de votre question) est la meilleure façon de gérer ce problème. – ACE

-1

si vous avez besoin de trouver un document spécifique, puis ajouter quelque chose:

flag=db.foo.find({"_id":333}) 
    try: 
     if flag[0]['_id']: 
      db.foo.update({"_id":333},{"$set":{"name":"mongo"}}) 
    except: 
     print "none" 

mais si vous avez besoin de rechercher tous les documents et ajouter quelque chose à tous:

flag=db.foo.find() 
for row in flag: 
    db.foo.update({"_id":flag['_id']},{"$set":{"name":"mongo"}}) 
Questions connexes