2011-02-17 3 views
2

Il est un exemple sur les requêtes modèle/mise à jour des données de vote à Mongo:
http://www.mongodb.org/display/DOCS/MongoDB+Data+Modeling+and+Rails#MongoDBDataModelingandRails-AtomicUpdatesmodélisation des données Mongo/mises à jour pour le vote (haut et bas)

Cependant, je besoin à la fois haut et en bas voix (en gros, une personne peut soit voter ou voter vers le bas). En outre, je veux que l'électeur puisse changer d'avis et changer de vote en faveur de la rétrogradation ou inversement (la liste des électeurs et le nombre total ne correspondent donc pas). Quel serait le meilleur modèle de données et l'appel correspondant de mise à jour?

Quel serait le meilleur modèle de données et appel de mise à jour correspondant?

Je vois deux possibilités, soit faire un

'votes': [{ 'user_id' : ... , 'vote': ±1 }] 

ou

'upvoters': [...], 'downvoters': [...] 

Mais je ne peux pas faire une requête de mise à jour pour la première encore, et deuxième ressemble un peu bizarre (mais ce n'est peut-être que moi).

+0

Si je me souviens bien, l'exemple donné dans la documentation MongoDB permettra -1 (non seulement plus 1) ... avez-vous essayé? Ou avez-vous besoin de connaître le nombre exact de votes négatifs? –

+0

Excellent commentaire. Oui, la raison en est que je veux laisser la personne changer d'avis et lancer un downvote où elle a déjà lancé un upvote, et l'exemple de mongodb ne le permet pas. Ajouté ceci au texte de question. –

Répondre

1

Le premier schéma semble être bon. Le deuxième schéma est difficile car lorsque l'utilisateur clique sur upvote et que downvote, vous devez ajouter userId à 'upvoters' que 'downvoters' et supprimer de 'upvoters' et vice versa. Je suppose qu'il vote la collection de quelque document (supposons qu'il questionne).

db.questions.update({votes.userId: .. },{ $set : { votes.$.vote : 1 } });//upvote 
db.questions.update({votes.userId: .. },{ $set : { votes.$.vote : -1 } });//down 

Et vous semble besoin de créer champ supplémentaire à l'intérieur de la collecte de questions pour calculer la somme des voix haut/bas:

db.questions.update({_id: .. },{ $inc : { votesCount : 1 } }); //up vote 
db.questions.update({_id: .. },{ $inc : { votesCount : -1 } }); // down vote 

Si vous avez besoin d'ajouter un nouvel utilisateur à un tableau de votes utiliser

Possitional operator.

+0

Il vaut la peine de noter qu'une décrémentation de -1 pour un utilisateur qui a déjà placé un upvote n'aboutira pas à un downvote et vice-versa quel que soit le schéma avec lequel l'OP décide d'aller.Ce serait -2 ou +2 respectivement. –

+0

Cette mise à jour fonctionne si l'utilisateur est déjà dans la collection, mais il ne correspond pas si l'utilisateur ne l'est pas. Dois-je commencer par une commande $ ne/$ push? –

+0

Oui, il faut d'abord vérifier que cet utilisateur existe ou non, et que l'utilisateur n'existe pas $ push sinon mettre à jour. –

1

Cela semble beaucoup plus simple d'utiliser le second schéma.

Document: { name: "name", 
      upvoters: [name1, name2, etc], 
      downvoters: [name1, name2, etc], 
      } 

Pour obtenir total des voix que vous pouvez obtenir le doc et utiliser doc.upvoters.length-doc.downvoters.length (début de chaque document avec des tableaux de upvoters et downvoters étant [])

Pour enregistrer tout upvote par l'utilisateur « x » sur le point « c » just do:

db.votes.update({name:"c"},{$addToSet:{upvotes:"x"},$pull:{downvotes:"x"}}) 

Ceci est atomique et il a l'avantage de faire la même chose, même si vous avez 10 fois. Il vous évite également de devoir vérifier si "x" a déjà voté pour "c" et de quelle manière.

Pour enregistrer downvote simplement inverser:

db.votes.update({name:"c"},{$addToSet:{downvotes:"x"},$pull:{upvotes:"x"}}) 
Questions connexes