2017-10-18 10 views
0

J'essaie de comprendre si ce que je veux faire est encore possible dans Mongodb. Je suis ouvert à toutes sortes de suggestions concernant des moyens plus appropriés pour réaliser ce dont j'ai besoin.agrégation et le tri basé sur une relation Mongodb

Actuellement, j'ai 2 collections:

véhicules (Contient des données de véhicules tels que la marque et le modèle Ces données peuvent être très non structurées, ce qui est la raison pour laquelle je me suis tourné vers MongoDB pour cela.)

vues (simplement contient un IP, une date/heure que le véhicule a été regardé et le vehicle_id. Il pourrait y avoir des milliers de vues)

Je dois retourner une liste de véhicules qui ont des vues entre 2 dates. La liste devrait inclure le nombre de vues. Je dois être en mesure de trier par le nombre de vues en plus de l'un des champs de véhicules habituels. Donc, pour être clair, si un véhicule a eu 1000 vues, mais seulement 500 entre les dates données, le nombre devrait retourner 500.

Je suis assez sûr que je pourrais effectuer cette requête sans aucun problème dans MySQL - cependant, essayer de stocker les données du véhicule dans MySQL a été un vrai casse-tête dans le passé et cela a été génial de passer à Mongo où je peux facilement ajouter de nouveaux champs de données et ne pas m'inquiéter de la structure de ma base de données.

Qu'en pensez-vous? TIA!

Répondre

0

En fin de compte, c'est tout à fait possible. Il m'a fallu beaucoup de temps pour obtenir ma tête, alors je suis l'afficher pour les futures recherches google ...

db.statistics.aggregate({ 
    $match: { 
    branch_id: { $in: [14] } 
    } 
}, { 
    $lookup: { 
    from: 'vehicles', localField: 'vehicle_id', foreignField: '_id', as: 'vehicle' 
    } 
}, { 
    $group: { 
    _id: "$vehicle_id", 
    count: { $sum: 1 }, 
    vehicleObject: { $first: "$vehicle" } 
    } 
}, { $unwind: "$vehicleObject" }, { 
    $project: { 
    daysInStock: { $subtract: [ new Date(), "$vehicleObject.date_assigned" ] }, 
    vehicleObject: 1, 
    count: 1 
    } 
}, { $sort: { count: -1 } }, { $limit: 10 }); 

Pour expliquer ce qui précède: Le cadre global MongoDB est la voie à suivre pour le complexe requêtes comme ça. Premièrement, je lance un $ match pour filtrer les enregistrements. Ensuite, nous utilisons $ lookup pour récupérer l'enregistrement du véhicule. Il est à noter ici que c'est une relation de plusieurs à un ici (beaucoup de statistiques, chacun ayant un seul véhicule). Je peux ensuite regrouper sur le champ vehicle_id, ce qui me permettra de renvoyer un enregistrement par véhicule en comptant le nombre de statistiques dans le groupe. Comme il s'agit d'un groupe, nous avons techniquement beaucoup de copies de ce même document de véhicule dans chaque groupe, donc j'ajoute juste le premier dans la variable vehicleObject. Ce serait bien, mais $ premier a tendance à retourner un tableau avec une seule entrée (inutile à mon avis), alors j'ai ajouté la scène déroulant $ pour tirer le véhicule réel. J'ai ensuite ajouté une étape de projet $ pour calculer un champ supplémentaire, triés par le nombre décroissant et limité les résultats à 10.

Et prends une grande respiration :)

J'espère que quelqu'un aide. Si vous connaissez une meilleure façon de faire ce que j'ai fait, alors je suis ouvert aux suggestions pour améliorer.