38 votes

Tri des vues CouchDB par valeur

Je suis du test de CouchDB pour voir comment il pourrait gérer la journalisation des résultats de recherche. Ce que je voudrais faire est de produire un point de vue où je peux produire le top des requêtes à partir des résultats. Pour le moment j'ai quelque chose comme ceci:

Exemple de document de la partie

{
  "query": "+dangerous +dogs",
  "hits": "123"
}

Fonction Map (Pas exactement ce dont j'ai besoin/envie, mais c'est assez bon pour les tests)

function(doc) {
  if (doc.query) {
    var split = doc.query.split(" ");
    for (var i in split) {
      emit(split[i], 1);
    }
  }
}

Fonction De Réduction

function (key, values, rereduce) {
  return sum(values);
}

Maintenant, cela va me faire des résultats dans un format où un terme de la requête est la clé et le nombre de ce terme sur la droite, ce qui est excellent. Mais j'aimerais qu'il a ordonné par la valeur, non pas la clé. De les sons de celui-ci, ce n'est pas encore possible avec CouchDB.

Si quelqu'un a une idée de comment je peux obtenir un point de vue où j'ai commandé la version des termes de la requête & leur compte? Je suis très nouveau à CouchDB et je ne peux pas penser comment allais-je écrire les fonctions nécessaires.

25voto

JasonSmith Points 34470

Il est vrai qu'il n'y a pas de morts-réponse simple. Il existe plusieurs modèles mais.

  1. http://wiki.apache.org/couchdb/View_Snippets#Retrieve_the_top_N_tags. Je ne suis pas personnellement aime, parce qu'ils reconnaissent que c'est un fragile de la solution, et le code n'est pas de détente-à la recherche.

  2. Avi réponse, qui est de les trier en mémoire dans votre application.

  3. couchdb-lucene qui il semble que tout le monde se retrouvent à devoir éventuellement!

  4. Ce que j'aime, c'est ce que Chris a dit en Avi de devis. Détendez-vous. Dans CouchDB, les bases de données sont légers et excel en vous donnant un point de vue unique de vos données. Ces jours-ci, le buzz est tout au sujet de filtre de réplication qui est tout au sujet de tranchant sous-ensembles de données à mettre en DB distinct.

    De toute façon, les bases sont simples. Vous prenez votre .rows à partir de la sortie de la vue et de l'insérer dans un DB distinct qui émet simplement posés sur le comte. Une astuce supplémentaire est d'écrire une simple _list fonction. Les listes de "rendre" les premières canapé sortie dans différents formats. Votre _list de la fonction de sortie

    { "docs":
        [ {..view row1...},
          {..view row2...},
          {..etc...}
        ]
    }
    

    Ce qui n'est le format de la sortie de la vue exactement de la manière dont l' _bulk_docs API exige. Maintenant, vous pouvez pipe curl directement dans un autre curl:

    curl host:5984/db/_design/myapp/_list/bulkdocs_formatter/query_popularity \
     | curl -X POST host:5984/popularity_sorter/_design/myapp/_view/by_count
    
  5. En fait, si votre liste de fonction peut gérer tous les docs, vous pouvez juste avoir les trier lui-même et de le retourner au client triés.

13voto

Avi Flax Points 14898

C' est venu sur le CouchDB-user mailing liste, et Chris Anderson, l'un des principaux développeurs, a écrit:

C'est une demande commune, mais non pris en charge directement par CouchDB est vues -- pour ce faire, vous aurez besoin de copier le groupe-réduire la requête de une autre base de données, et de construire une vue de trier par valeur.

C'est un compromis que nous faisons dans la faveur de la plage dynamique des requêtes et différentiels d'index.

J'avais besoin de le faire récemment, et j'ai fini par le faire dans mon application de niveau. C'est facile à faire en JavaScript:

db.view('mydesigndoc', 'myview', {'group':true}, function(err, data) {

    if (err) throw new Error(JSON.stringify(err));

    data.rows.sort(function(a, b) {
        return a.value - b.value;
    });

    data.rows.reverse(); // optional, depending on your needs

    // do something with the data…
});

Cet exemple fonctionne en Node.js et utilise nœud-couchdb, mais il peut facilement être adapté pour fonctionner dans un navigateur ou un autre environnement JavaScript. Et bien sûr, le concept est transférable à tout langage de programmation/environnement.

HTH!

2voto

Je ne suis pas sûr du résultat que vous avez obtenu, mais je suis certain que cela devrait faire l'affaire:

emit([doc.hits, split[i]], 1);

Les règles de tri sont définies dans la documentation.

2voto

user599515 Points 11

Basé sur Avi réponse, je suis venu avec cette Couchdb liste en fonction de ce qui a fonctionné pour mes besoins, qui est simplement un rapport de la plus populaire des événements (clé=nom de l'événement, valeur=participants).

ddoc.les listes.eventPopularity = function(req, res) {
 start({ en-têtes : { "Content-type" : "text/plain" } });
 var data = []
 while(ligne = getRow()) {
les données.push(ligne);
}
 les données.de tri(function(a, b){
 retour une.la valeur b.valeur;
}).reverse();
 for(i in data) {
 send(data[i].valeur + ': '+ data[i].clé + "\n");
}
}

Pour référence, voici la vue correspondante de la fonction:

ddoc.les vues.eventPopularity = {
 carte : function(doc) {
 si(doc.type == 'utilisateur') {
 for(i in doc.les événements) {
 émettre(doc.événements[i].event_name, 1);
}
}
},
 réduire : '_count'
}

Et la sortie de la fonction de liste (ciselée):

165: Conception Axée sur l'Innovation: Comment les Concepteurs de Faciliter le Dialogue
165: Vos Clients Sont-ils d'une Foule ou d'une Communauté?
164: Les Médias Sociaux Mythbusters
163: N'ayez pas Peur De la Créativité! Tout Peut Arriver
159: les Organismes Doivent Penser Comme Sociétés de Logiciels?
158: L'Expérience Client: Les Futures Tendances & Insights
156: L'Accidentel, de l'Écrivain: la Grande Copie sur le Web pour tout le monde
155: Pourquoi Tout est Incroyable, Mais Personne n'est Content

0voto

Melug Points 665

Je pense que toutes les solutions ci-dessus vont casser les performances de couchdb. Je suis très nouveau dans cette base de données. Comme je le sais, les vues de couchdb préparent les résultats avant de les interroger. Il semble que nous devons préparer les résultats manuellement. Par exemple, chaque terme de recherche résidera dans la base de données avec le nombre de résultats. Et lorsque quelqu'un effectue une recherche, ses termes de recherche sont recherchés et le nombre de hits augmente. Lorsque nous voulons voir la popularité des termes de recherche, ils émettront (hitcount, searchterm) paire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X