2010-04-06 4 views
10

Comment est-ce que j'exécuterais une requête équivalente à "choisir le top 10" dans le divan db?Choisir top/latest 10 dans couchdb?

Par exemple, j'ai un « schéma » comme ceci:

title body modified 

et je veux sélectionner les 10 derniers documents modifiés.

Comme un bonus supplémentaire si quelqu'un peut trouver un moyen de faire la même chose par catégorie. Donc pour:

title category body modified 

retourner une liste des 10 derniers documents dans chaque catégorie.

Je me demande simplement si une telle requête est possible dans couchdb.

+0

Y a-t-il une raison pour laquelle vous ne voulez pas le faire manuellement? Première requête pour les catégories disponibles, puis interrogez les listes par catégorie. Faire la deuxième requête par lot, c'est presque comme sur la requête. –

+0

Je peux le faire oui - mais ma question est de savoir si quelque chose comme ceci est possible dans couchdb, dans une requête. Par exemple, on peut le faire en sql avec une instruction select imbriquée complexe complexe. – drozzy

Répondre

3

voici ce que vous devez faire.

fonction de la carte

function(doc) 
{ 
    if (doc.category) 
    { 
    emit(['category', doc.category], doc.modified); 
    } 
} 

alors vous avez besoin d'une fonction de liste qui les groupes, vous pourriez temped d'abuser d'un réduire et faire cela, mais il sera probablement jeter des erreurs en raison de ne pas réduire assez vite avec de grands ensembles de données.

function(head, req) 
{ 
    % this sort function assumes that modifed is a number 
    % and it sorts in descending order 
    function sortCategory(a,b) { b.value - a.value; } 
    var categories = {}; 
    var category; 
    var id; 
    var row; 
    while (row = getRow()) 
    { 
    if (!categories[row.key[0]]) 
    { 
     categories[row.key[0]] = []; 
    } 
    categories[row.key[0]].push(row); 
    } 
    for (var cat in categories) 
    { 
    categories[cat].sort(sortCategory); 
    categories[cat] = categories[cat].slice(0,10); 
    } 
    send(toJSON(categories)); 
} 

vous pouvez obtenir toutes les catégories top 10 maintenant avec

http://localhost:5984/database/_design/doc/_list/top_ten/by_categories 

et obtenir la documentation avec

http://localhost:5984/database/_design/doc/_list/top_ten/by_categories?include_docs=true 

maintenant vous pouvez interroger ce avec une gamme multiple POST et limite les catégories

curl -X POST http://localhost:5984/database/_design/doc/_list/top_ten/by_categories -d '{"keys":[["category1"],["category2",["category3"]]}' 

vous pouvez également ne pas coder le 10 et transmettre le nombre à travers la variable req.

Voici un peu plus Voir/Liste trickery.

+0

Cool, je vais tester et revenir à vous! – drozzy

+0

Je n'ai pas testé cette réponse, mais je l'accepte de toute façon car je ne travaille plus avec couchdb. – drozzy

7

Pour obtenir les 10 premiers documents de votre base de données, vous pouvez utiliser l'option de requête de limite. E.g. appeler

http://localhost:5984/yourdb/_design/design_doc/_view/view_name?limit=10 

Vous obtenez les 10 premiers documents.

Les lignes de vue sont triées par clé; l'ajout de descending = true dans la chaîne de requête inverse leur ordre. Vous pouvez également n'émettre que les documents qui vous intéressent en utilisant à nouveau la chaîne de requête pour sélectionner les clés qui vous intéressent. Donc, selon vous, vous écrivez votre fonction carte comme:

function(doc) { 
    emit([doc.category, doc.modified], doc); 
} 

Et vous interrogez comme ceci:

http://localhost:5984/yourdb/_design/design_doc/_view/view_name?startkey=["youcategory"]&endkey=["youcategory", date_in_the_future]&limit=10&descending=true 
+0

Cette seconde requête sélectionnera-t-elle réellement les 10 derniers éléments dans chacune des catégories? Ou juste 10 derniers articles d'une catégorie? – drozzy

+0

Oups. J'ai mal interprété votre question. Il sélectionne les 10 derniers éléments d'une catégorie. – filippo

0

légère correction. il ne triait pas jusqu'à ce que j'ai ajouté le mot-clé "return" dans votre fonction sortCategory.Cela devrait être comme ceci:

function sortCategory(a,b) { return b.value - a.value; }