2017-10-17 12 views
3

je les structures de données suivantes:

collection playlist:

{ 
    _id:123, 
    artistId:959789, 
    title:'playlist1', 
    tracks:[{trackId:123456,createdDate:03.02.2017}, 
     {trackId:213556,createdDate:04.02.2017}, 
     {trackId:956125,createdDate:05.02.2017}] 
}, 
{ 
    _id:456, 
    artistId:456456, 
    title:'playlist2', 
    tracks:[{trackId:956336,createdDate:03.02.2017}, 
     {trackId:213556,createdDate:09.02.2017}, 
     {trackId:785556,createdDate:011.02.2017}] 
}, 
{ 
    _id:456, 
    artistId:456456, 
    title:'playlist3', 
    tracks:[{trackId:636985,createdDate:01.02.2017}, 
     {trackId:456585,createdDate:06.02.2017}, 
     {trackId:785556,createdDate:09.02.2017}] 
} 

Le trackId dans le tableau des pistes d'une liste de lecture est la _id d'une piste collection piste

pistes collection:

{_id:956336,title:'abc'}, 
{_id:785556,title:'cdf'}, 
{_id:456585,title:'ghi'}, 
{_id:213556,title:'xyz'}, 
{_id:636985,title:'lmn'} 

Ce que j'ai fait était un agrégat $lookup en utilisant le trackId dans le tableau tracks et j'ai obtenu le résultat. Mais le playlistTracks a été trié dans un autre ordre et non dans l'ordre de la commande tracks.

{ 
     $match: {artistId: 456} 
}, 
{ 
    $lookup: { 
      from: 'tracks', 
      localField: 'tracks.trackId', 
      foreignField: '_id', 
      as: 'playlistTracks' 
     } 
}, 

Maintenant, ce que je dois est d'obtenir la liste des listes de lecture par un artiste en particulier ayant la structure suivante: Le playlistTracks doit être classée dans l'ordre sur le createdDate dans le tableau tracks.

{ 
    _id:456, 
    title:'playlist2', 
    tracks:[{trackId:636985,createdDate:01.02.2017}, 
     {trackId:456585,createdDate:06.02.2017}, 
     {trackId:785556,createdDate:09.02.2017}] 
    playlistTracks:[{_id:956336,title:'abc'}, 
      {_id:213556,title:'xyz'}, 
      {_id:785556,title:'cdf'}] 
}, 
{ 
    _id:456, 
    title:'playlist2', 
    tracks:[{trackId:636985,createdDate:01.02.2017}, 
     {trackId:456585,createdDate:06.02.2017}, 
     {trackId:785556,createdDate:09.02.2017}] 
    playlistTracks:[{_id:636985,title:'lmn'}, 
      {_id:456585,title:'ghi'}, 
      {_id:785556,title:'cdf'}] 
} 

Répondre

1

Suivez les étapes ci-dessous

1 unwind the tracks array in playlist collection 
2 $lookup match with tracks collection 
3 add createddate of tracks array to lookup result as a new key 
4 sort based on new key 
5 group the results for your requirements 
+0

Merci beaucoup. Cela marche!!!! –

1

Ce sont les documents que j'ai ajouté, de reproduire votre cas d'utilisation:

collection Playlist

{ 
    "_id" : NumberInt(123), 
    "artistId" : NumberInt(959789), 
    "title" : "playlist1", 
    "tracks" : [ 
     { 
      "trackId" : NumberInt(123456), 
      "createdDate" : "03.02.2017" 
     }, 
     { 
      "trackId" : NumberInt(213556), 
      "createdDate" : "04.02.2017" 
     }, 
     { 
      "trackId" : NumberInt(956125), 
      "createdDate" : "05.02.2017" 
     } 
    ] 
} 
{ 
    "_id" : NumberInt(456), 
    "artistId" : NumberInt(456456), 
    "title" : "playlist2", 
    "tracks" : [ 
     { 
      "trackId" : NumberInt(956336), 
      "createdDate" : "03.02.2017" 
     }, 
     { 
      "trackId" : NumberInt(213556), 
      "createdDate" : "09.02.2017" 
     }, 
     { 
      "trackId" : NumberInt(785556), 
      "createdDate" : "11.02.2017" 
     } 
    ] 
} 
{ 
    "_id" : NumberInt(457), 
    "artistId" : NumberInt(456456), 
    "title" : "playlist3", 
    "tracks" : [ 
     { 
      "trackId" : NumberInt(636985), 
      "createdDate" : "01.02.2017" 
     }, 
     { 
      "trackId" : NumberInt(456585), 
      "createdDate" : "06.02.2017" 
     }, 
     { 
      "trackId" : NumberInt(785556), 
      "createdDate" : "09.02.2017" 
     } 
    ] 
} 

J'ai changé la dernière _id en double sur la collection de playlist avec _id: 457 Je ne sais pas comment vous pourriez avoir deux documents avec le même _id. _id Le champ doit être unique. Et je ne suis pas sûr de comprendre le résultat souhaité, car dans votre requête $match, vous écrivez ce qui suit: $match: {artistId: 456} mais dans vos données il n'y a pas artiseId avec .

et cette date

{TrackID: 785556, CreatedDate: 011.02.2017}

du document id_ 456 j'ai changé pour

{trackId:785556,createdDate:"11.02.2017"} 

cause de la date avait l'air bizarre. Il semble également que vos champs de date sont des chaînes, car cela ne ressemble certainement pas à un champ de date. De toute façon, le $sort fonctionne pour les deux cas d'utilisation.

La collection de pistes Je suis parti comme dans votre exemple.

Donc, cela semble être ce dont vous avez besoin?

db.playlist.aggregate([ 
{ 
     $match: {_id: {$in: [456]}} 
}, 
{ $unwind: "$tracks"}, 
{$sort: {"tracks.createdDate": 1}}, 
{ 
    $lookup: { 
      from: 'tracks', 
      localField: 'tracks.trackId', 
      foreignField: '_id', 
      as: 'playlistTracks' 
     } 
}, 
{ 
    $group:{ 
     _id: "$_id", 
     artistId: {$first: "$artistId"}, 
     title: {$first: "$title"}, 
     tracks: { $push: { item: "$tracks.trackId", quantity: "$tracks.createdDate" } }, 
     playlistTracks: { $push: "$playlistTracks" } 
    } 
} 
]) 

Ceci met les deux tableaux dans le même ordre.Vous pouvez spécifier ici {$sort: {"tracks.createdDate": 1}} si vous voulez ascendant ou descendant -1 ordre

Alors avant de chercher les champs vous pouvez vous détendre et trier votre liste de lecture. espère que cela fonctionne

+0

En fait, je veux le résultat de la 'lookup' de $ à trier en utilisant' createdDate'. Si nous '$ unwind' et' $ sort' de cette façon, le tableau 'tracks' est trié. –

+0

Désolé j'ai mal compris votre question, je mettrai à jour ma réponse. –

+0

Merci beaucoup pour l'effort. Je l'ai essayé. Mais ne fonctionne pas la façon dont je veux le résultat –