J'essaie d'obtenir Mongodb à upérez plusieurs enregistrements avec la requête suivante, à l'aide de Mongomapper et du pilote Mongo Ruby.
{ "_id" : ObjectId("4d6babbac0d8bb8238d02099"), "event_id" : 1, "visit" : 2 }
3 Réponses :
Ceci - correctement - n'entrera pas d'enregistrements avec event_id 1 ou 2 si elles n'existent pas déjà p>
Ceci est parce que la partie w.r.t. Insertion des lots avec Ruby, je pense qu'il est possible que le lien suivant suggère - bien que je n'ai utilisé que le pilote Java: Insertion / mise à jour par lots à l'aide de Mongoid? P> db.fooo.update ({event_id: {$ in: [1,2]}}, {$ inc: {visitez: 1}}, true, true) code> p> p> p>
objnew code> de la requête (voir http://www.mongodb.org/display/docs/updating#Updating-UpserSterSwithModificateurs ) n'a pas de valeur pour le champ event_id code>. En conséquence, vous aurez besoin d'au moins x + 1 voyages dans la base de données, où X est le nombre d'événements_ids, afin de vous assurer que vous insérez un enregistrement si on n'existe pas pour un événement particulier (le +1 vient de la requête ci-dessus. , qui augmente le compteur de visites pour les enregistrements existants). Pour le dire d'une manière différente, comment Mongodb sait-il que vous souhaitez utiliser la valeur 2 pour l'événement_id et non 1? Et pourquoi pas 6? P>
Pour clarifier, écrit pour la spécification BSON est en réalité "Batchable" par défaut. La plupart des pilotes prennent en charge une forme de mises à jour / inserts par lots, mais le Mongoïde n'est pas un pilote et peut ne pas prendre en charge toutes les fonctionnalités.
Qu'est-ce que vous êtes après est le Rechercher et modifier la commande avec l'option upert défini sur true. Voir Exemple à partir de la suite de tests Mongo (même liée à dans le trouver et modifier docs) pour un exemple qui ressemble beaucoup à ce que vous décrivez dans votre question. P>
J'ai trouvé un moyen de faire cela à l'aide de l'opérateur EVAL pour l'exécution du code côté serveur. Voici le code SNIPPIT:
def batchpush(body, item_opts = {})
@batch << {
:body => body,
:duplicate_key => item_opts[:duplicate_key] || Mongo::Dequeue.generate_duplicate_key(body),
:priority => item_opts[:priority] || @config[:default_priority]
}
end
def batchprocess()
js = %Q|
function(batch) {
var nowutc = new Date();
var ret = [];
for(i in batch){
e = batch[i];
//ret.push(e);
var query = {
'duplicate_key': e.duplicate_key,
'complete': false,
'locked_at': null
};
var object = {
'$set': {
'body': e.body,
'inserted_at': nowutc,
'complete': false,
'locked_till': null,
'completed_at': null,
'priority': e.priority,
'duplicate_key': e.duplicate_key,
'completecount': 0
},
'$inc': {'count': 1}
};
db.#{collection.name}.update(query, object, true);
}
return ret;
}
|
cmd = BSON::OrderedHash.new
cmd['$eval'] = js
cmd['args'] = [@batch]
cmd['nolock'] = true
result = collection.db.command(cmd)
@batch.clear
#pp result
end
Pas exactement sûr de ce que le comportement prévu est. Est-ce "S'il y a un événement, augmente son
visitent code> comptent, sinon créez un nouvel événement et définissez sonvisiter code> comptez sur 1"? Si oui, quel serait leevent_id code> pour des événements nouvellement insérés?