$ lookup结果使用另一个数组中的键进行排序

时间:2017-10-17 10:49:32

标签: arrays node.js mongodb sorting aggregate

我有以下数据结构:

播放列表集合:

$('*[data-visual-id="1"]').css({'display': 'none'});

播放列表的曲目数组中的{ _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}] } 是曲目集合中曲目的trackId

追踪集合:

_id

我所做的是使用{_id:956336,title:'abc'}, {_id:785556,title:'cdf'}, {_id:456585,title:'ghi'}, {_id:213556,title:'xyz'}, {_id:636985,title:'lmn'} 数组中$lookup的汇总trackId,我得到了结果。但tracks按其他顺序排序,而不是按playlistTracks数组顺序排列。

tracks

现在我需要的是获得具有以下结构的特定艺术家的播放列表列表: { $match: {artistId: 456} }, { $lookup: { from: 'tracks', localField: 'tracks.trackId', foreignField: '_id', as: 'playlistTracks' } }, 应按照playlistTracks数组中createdDate的顺序排序。

tracks

2 个答案:

答案 0 :(得分:1)

所以这些是我添加的文件,用于重现您的用例:

播放列表集

{ 
    "_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"
        }
    ]
}

我使用_id:457更改了播放列表集合中的最后一个重复_id。我不知道如何使用相同_id的两个文档。 _id字段必须是唯一的。我不确定我是否理解您所需的结果,因为在您的$match查询中,您写了以下内容:$match: {artistId: 456}但在您的数据中, artiseId 456

和这个日期

  

{trackId:785556,createdDate:011.02.2017}

从文件id_ 456我改为

{trackId:785556,createdDate:"11.02.2017"} 

导致日期看起来很奇怪。它看起来也像你的日期字段是字符串,因为它肯定看起来不像日期字段。无论哪种方式,$sort都适用于两个用例。

我在示例中留下的曲目集合

所以这似乎是你需要的?

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" }
    }
}
])

这使两个数组的顺序相同。如果您想要升序或降序{$sort: {"tracks.createdDate": 1}}订单

,可以在此处指定-1

因此,在查找字段之前,您可以展开并对播放列表数组进行排序。 希望这有效

答案 1 :(得分:1)

按照以下步骤

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