web-dev-qa-db-fra.com

Groupe MongoDB par éléments internes du tableau

J'ai une liste d'articles, et chacun d'eux a une propriété de tableau qui répertorie les différentes personnes mentionnées en eux:

_id: {
    $oid: "52b632a9e4f2ba13c82ccd23"
},
providerName: "The Guardian",
url: "http://feeds.theguardian.com/c/34708/f/663860/s/3516cebc/sc/38/l/0L0Stheguardian0N0Cmusic0C20A130Cdec0C220Cwaterboys0Efishermans0Eblues0Etour0Ehammersmith/story01.htm",
subject: "The Waterboys – review",
class_artist: [
    "paul mccartney"
]

J'ai essayé (sans succès) d'obtenir une liste de tous les artistes individuels (class_artist), en fonction du nombre d'articles dans lesquels ils ont été tagués au cours des 7 derniers jours.

Je suis allé jusqu'à:

var date = new Date();
date.setDate(date.getDate() - 7);

db.articles.group({
    key: { class_artist: 1 },
    cond: { class_date: { $gt: date } },
    reduce: function ( curr, result ) { result.cnt++; },
    initial: { cnt : 0 }
}).sort({cnt: -1});

Mais malheureusement, il ne les compte pas en fonction des valeurs de tableau individuelles, mais par des compositions de tableau (c'est-à-dire des listes d'artistes).

J'ai essayé d'utiliser le $unwind, mais n'ont pas pu le faire fonctionner.

36
Gil Adirim

Quel cadre utilisez-vous? Ce n'est pas MongoDB Shell et ressemble à un wrapper étrange MapReduce . Dans ce cas, $ unwind ne serait pas disponible, et vous en avez besoin pour l'utilisateur dans le framework d'agrégation . Voici ce que vous voulez dans le mongo Shell:

db.articles.aggregate([
  {$match: { class_date: { $gte: date } } },
  {$project: { _id: 0, class_artist: 1 } },
  {$unwind: "$class_artist" },
  {$group: { _id: "$class_artist", tags: { $sum: 1 } }},
  {$project: { _id: 0,class_artist: "$_id", tags: 1 } },
  {$sort: { tags: -1 } }
])

Si efficacement:

  1. Filtre par date car vous avez déjà défini un var pour les 7 derniers jours
  2. Projet seulement le ou les champs dont nous avons besoin {Nous n'en avons besoin que d'un! }
  3. Dérouler le tableau donc nous avons maintenant un enregistrement pour chaque élément du tableau dans chaque document
  4. Groupe sur l'artiste à partir des documents développés
  5. Projetez dans un format de document que vous pouvez utiliser en tant que groupe décousu avec _id
  6. Trier les résultats dans l'ordre inverse pour voir le haut balisé en premier

Et la grande chose à propos de l'agrégation est que vous pouvez progressivement construire ces étapes pour voir ce qui se passe.

Secouez et faites cuire dans votre propre implémentation de pilote ou infrastructure ODM selon les besoins.

109
Neil Lunn