【问题标题】:Mongodb sort by in arrayMongodb在数组中排序
【发布时间】:2019-05-07 08:49:02
【问题描述】:

有没有办法按给定的数组排序?

类似这样的:

const somes = await SomeModel.find({}).sort({'_id': {'$in': [ObjectId('sdasdsd), ObjectId('sdasdsd), ObjectId('sdasdsd)]}}).exec()

我寻找的是一种获得解决方案的方法,获取集合的所有文档并按文档的 _id 是否与给定数组之一匹配进行排序。

一个例子:

我们有专辑收藏和歌曲收藏。在专辑集合中,我们存储属于专辑的歌曲的 ID。

我想获取歌曲,但如果歌曲在专辑中,请将它们放在数组的前面。

我按如下方式解决了这个问题,但它看起来有点 hacky:

const songs = await SongMode.find({}).skipe(limit * page).limit(limit).exec();
const album = await AlbumModel.findById(id).exec();

if(album) {
    songArr = album.songs.slice(limit * page);

    for(let song of album.songs) {
        songs.unshift(song);
        songs.pop();
    }
}

【问题讨论】:

  • 你能解释一下吗?项目包含什么?
  • items 是一个_ids数组
  • 您能否详细说明“按给定数组排序”的含义?请更清楚、更详细地了解文档的外观以及您希望看到的结果行为。您在此处提供的内容没有什么可取之处。
  • @B.Fleming, Anthony Winzlet 我更新了问题以更清楚。
  • 您可以使用$indexOfArray。类似db.collection.aggregate([ { "$addFields": { "order": { "$indexOfArray": [arrayOfIds, "$_id"] } } }, { "$sort": { "order": 1 } } ])

标签: javascript node.js mongodb mongoose nosql


【解决方案1】:

这不能使用普通的.find().sort() 来完成。相反,您将需要使用 MongoDB 聚合管道 (.aggregate())。具体来说,您需要执行以下操作:

  1. 执行$projection,这样如果_id$in 数组,则新的sort_field 将被赋予值1,否则赋予值0
  2. 执行$sort,以便对新的sort_field 进行降序排序。

如果您使用的是 MongoDB 3.4 或更高版本,那么这很容易,因为 $addFields 运算符:

const your_array_of_ids = [
    ObjectId('objectid1'),
    ObjectId('objectid2'),
    ObjectId('objectid3')
];

SomeModel.aggregate([
    { '$addFields': {
        'sort_field': { '$cond': {
            'if': { '$in': [ '$_id', your_array_of_ids ] },
            'then': 1,
            'else': 0
        }}
    }},
    { '$sort': {
        'sort_field': -1
    }}
]);

如果您使用的是旧版本的 MongoDB,则解决方案类似,但您将使用 $project 而不是 $addFields。此外,您需要明确包括所有其他想要包含的字段,否则它们将被排除在结果之外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 2013-03-01
    • 2012-07-28
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    相关资源
    最近更新 更多