MongoDB 聚合:首先按现有值排序

bab*_*eir 5 mongoose mongodb node.js aggregation-framework

我的用户有这个字段:

interestedIn: [{
        type: String,
        enum: [
            'art',
            'sport',
            'news',
            'calture',
            ...
        ],
    }],
Run Code Online (Sandbox Code Playgroud)

我的视频有这个字段:

categories: [{
            type: String,
            enum: [
                'art',
                'sport',
                'news',
                'calture',
                ...
            ],
        }],
Run Code Online (Sandbox Code Playgroud)

所以我需要一个具有以下条件的视频查询:

  • 首先查询所有视频并按req.user.interestedIn 中的值排序。
  • 其余与req.user.interestedIn不匹配的视频进入最后。

我通过上述查询做到了这一点:

Video.aggregate([

        { '$match': {}},
        { '$unwind': '$categories' },
        { '$match': {categories: {$in: req.user.interestedIn}}},
        { '$group': {
            '_id': '$categories',
            'categories': { '$push': '$categories' }
        }},
        { '$sort': { 'categories': 1 } }
    ])
Run Code Online (Sandbox Code Playgroud)

这是结果:

   "videos": [
        {
            "_id": "art",
            "categories": [
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art"
            ]
        },
        {
            "_id": "news",
            "categories": [
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
   "videos": [
        {
            "_id": "art",
            "categories": [
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art",
                "art"
            ]
        },
        {
            "_id": "news",
            "categories": [
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news",
                "news"
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

use*_*814 4

您可以使用$setIntersection提取匹配元素,然后对$size匹配项进行计数。

$sort 匹配次数的降序文档。

就像是

Video.aggregate([ 
  {"$addFields":{ "numofmatches":{"$size":{"$setIntersection":["$categories", req.user.interestedIn]}}}}, 
  {"$sort":{"numofmatches":-1}} 
])
Run Code Online (Sandbox Code Playgroud)