2011-10-17 3 views
2

J'essaye de construire un (simple) twitter-clone qui utilise CouchDB comme Database-Backend. En raison de ses fonctionnalités réduites, j'en ai presque terminé avec le codage, mais il reste une chose que je ne peux pas résoudre avec CouchDB - le scénario par utilisateur.Construire un (simple) twitter-clone avec CouchDB

Comme avec twitter, le calendrier par utilisateur devrait afficher les tweets de toutes les personnes que je suis, dans un ordre chronologique. Avec SQL, c'est une Select-Statement assez simple, mais je ne sais pas comment la reproduire avec CouchDBs Map/Reduce.

Voici le SQL-déclaration j'utiliser un SGBDR:

SELECT * FROM tweets WHERE user_id IN [1,5,20,33,...] ORDER BY created_at DESC; 

schéma CouchDB détails

utilisateur-schéma:

{ 
    _id:xxxxxxx, 
    _rev:yyyyyy, 
    "type":"user", 
    "user_id":1, 
    "username":"john", 
    ... 
} 

Tweet-schéma:

{ 
"_id":"xxxx", 
"_rev":"yyyy", 
"type":"tweet", 
"text":"Sample Text", 
"user_id":1, 
... 
"created_at":"2011-10-17 10:21:36 +000" 
} 

Avec view collations il est assez simple d'interroger CouchDB pour une liste de "tous les tweets avec user_id = 1 classés chronologiquement".

Mais comment puis-je récupérer une liste de "tous les tweets qui appartiennent aux utilisateurs avec l'ID 1,2,3, ... classés par ordre chronologique"? Ai-je besoin d'un autre schéma pour mon application?

Répondre

0

La meilleure façon de le faire serait de sauver le created_at comme un horodatage puis créer une vue, et la carte tous les tweets à la user_id:

function(doc){ 
    if(doc.type == 'tweet'){ 
    emit(doc.user_id, doc); 
    } 
} 

requête alors la vue avec l'ID utilisateur de en tant que clés, et dans votre application les trient comme vous le souhaitez (la plupart ont une méthode de tri pour les tableaux).

Modifié une dernière fois - essayait de faire tout cela dans CouchDB ... voir révisions :)

+0

Je suis désolé, mais c'est mauvaise pratique. Vous ne réduisez pas à de petites et simples valeurs dans votre fonction de réduction - ce n'est pas comment les fonctions de réduction doivent être utilisées. –

+0

Je pense que c'est pourquoi il soulève un "reduce_overflow_error" – Railsmechanic

+0

Ici, supprimé la fonction de réduction et changé la fonction de la carte. @PartlyCloudy Je n'aurais pas dû utiliser une réduction comme ça, heureux maintenant? – Shedokan

0

Est-ce une application CouchDB uniquement? Ou utilisez-vous quelque chose entre les deux pour une logique d'affaires supplémentaire. Dans ce dernier cas, vous pouvez réaliser cela en exécutant plusieurs requêtes.

Cela peut inclure la fusion de différentes vues. Une autre approche consisterait à ajouter une liste de "lecteurs privés" pour chaque tweet. Il permet des vues (partielles) spécifiques à l'utilisateur, mais introduit également la complexité d'ajouter la liste des lecteurs pour chaque nouveau tweet, ou même de mettre à jour la liste en cas de nouveaux suiveurs ou d'opérations non suivies.

Il est important de penser aux opérations possibles et à leurs fréquences. Ainsi, lorsque vous créez des listes de tweets, il est préférable de transférer la complexité dans la manière d'intégrer les informations du lecteur dans vos documents (c'est-à-dire d'intégrer les lecteurs dans votre document tweet) et de créer facilement des indices de vue efficaces.

Si vous avez plusieurs modifications à vos données, il est préférable de concevoir votre base de données pour ne pas mettre à jour trop de documents existants en même temps. Essayez plutôt d'ajouter des données en ajoutant de nouveaux documents et en les regroupant via des vues complexes.

Mais vous avez montré une casse où l'index basé sur une liste simple (unidimensionnel) n'est pas suffisant. Vous auriez en fait besoin d'index secondaires pour filtrer par le temps et les identifiants d'utilisateur (étant donné que vous avez également besoin de plages partielles pour les deux). Mais ce n'est pas possible dans CouchDB, vous avez donc besoin de contourner le problème en déplaçant les données de "requête" dans vos documents et de les utiliser lors de la construction de la vue.

+0

J'utilise Sinatra (Ruby) pour la logique métier ... – Railsmechanic

Questions connexes