mongoose 在分页的填充字段中按字段排序(排序前无需查询所有父文档)

l5tcr1uw  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(153)

我有这些MongoDB模式:

var Wizard = new Schema({
    name  : { type: String }
, spell  : { type: Schema.ObjectId, ref: 'Spell' }
});

var Spell = new Schema({
    name    : { type: String }
,   damages : { type: Number }
});

字符串
如果我只是简单地查询文档,下面是示例JSON。

[{
    name: 'Gandalf',
    spell: {
            name: 'Fireball',
            damages: 20
        }
}, {
    name: 'Saruman',
    spell: {
            name: 'Frozenball',
            damages: 10
        }
}, {
    name: 'Radagast',
    spell: {
            name: 'Lightball',
            damages: 15
        }
}]


我想从Wizard模式中查询文档,但基于spell.damages进行排序。
我在网上探索的方法并不令人满意,因为它们通常涉及一个聚合管道,首先查询Wizard集合中的所有文档,填充spell字段,然后最后基于spell.damages字段进行排序。
我想实现的是能够对查询进行分页,同时根据spell.damages字段进行排序。具体来说,我想避免管道首先查询Wizard集合中的所有文档的步骤,因为我假设当该集合中的文档很大时,成本会很高。
我想到的唯一方法是将spell.damages字段复制到Wizard文档中,但这导致在值更改时需要维护Wizard集合和Spell集合上的信息。
有人有什么建议或其他方法吗?

wmomyfyw

wmomyfyw1#

我能想到的提高性能的唯一方法是创建一个按需物化视图,因为:
按需示例化视图提供比标准视图更好的读取性能,因为它们是从磁盘读取的,而不是作为查询的一部分进行计算。这种性能优势会随着管道的复杂性和聚合数据的大小而增加。
在mongosh中创建视图函数:

sortWizardsWithSpells = function() {
    db.wizards.aggregate( [
        { $lookup: { from: 'spells', localField: 'spell', foreignField:'_id', as: 'spell' }},
        { $unwind: { path: "$spell" } },
        { $sort: { "spell.damages" : 1 } },
        { $merge: { into: "wizardsWithSpells", whenMatched: "replace" } }
    ] );
};

字符串
执行函数以填充集合(视图):

sortWizardsWithSpells();


现在,当你在wizardsWithSpells集合(视图)上执行查询时:

db.wizardsWithSpells.find()


您可以对预先填充的视图进行分页。

备注:每当需要刷新视图时,您都需要执行sortWizardsWithSpells函数。如果该视图需要频繁刷新,则这可能不是最佳选择。

相关问题