Mongoose Query:比较同一文档中的两个值

jua*_*rco 4 mongoose mongodb node.js

如何使用Mongoose查询Mongo集合以查找在两个属性之间具有特定关系的所有文档?

例如,如何查询characters集合以查找其currentHitPoints值小于其maximumHitPoints值的所有字符?或者那些projects有自己currentPledgedMoney比他们少pledgeGoal

我试过这样的事情:

mongoose.model('Character')
    .find({
        player: _currentPlayer
    })
    .where('status.currentHitpoints').lt('status.maximumHitpoints')
    .exec(callback)
Run Code Online (Sandbox Code Playgroud)

但是由于lt论证必须是a,我收到错误Number.如果我使用同样的事情$.status.maximumHitpoints(我希望Mongoose能够像进行收集操作那样解决它).

这是可以在查询中完成的吗?我希望如此,但不知道如何.否则我可以过滤整个集合,underscore但我怀疑这将对性能产生负面影响.

PS:我也尝试过使用类似的方法进行find呼叫,没有骰子.

Tom*_*iha 7

MongoDB 3.6 及以上版本支持查询语言内的聚合表达式:

db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )
Run Code Online (Sandbox Code Playgroud)

https://docs.mongodb.com/manual/reference/operator/query/expr/


jua*_*rco 6

感谢Aniket在问题评论中的建议,我发现使用以下语法可以使用Mongoose完成相同的操作:

mongoose.model('Character')
    .find({
        player: _currentPlayer
    })
    .$where('this.status.currentHitpoints < this.status.maximumHitpoints')
    .exec(callback)
Run Code Online (Sandbox Code Playgroud)

请注意,$where使用该where方法而不是方法.

编辑:为了扩展下面的Derick的评论,一个性能更敏感的解决方案是在Mongoose模式中包含一个包含比较结果的布尔属性,并在每次保存文档时更新它.这可以通过使用Mongoose Schema插件轻松实现,所以你会有类似的东西:

var CharacterSchema = new mongoose.Schema({
    // ...
    status: {
        hitpoints: Number,
        maxHitpoints: Number,
        isInFullHealth: {type: Boolean, default: false}
    }
})
.plugin(function(schema, options) {
     schema.pre('save', function(next) {
         this.status.isInFullHealth = (this.status.hitPoints >= this.status.maxHitpoints);

         next();
     })
 })
Run Code Online (Sandbox Code Playgroud)

  • 请记住,这种查询对于大型集合来说可能会变得很慢,因为它不使用索引.如果性能是个问题,那么解决方案是使用comparisson的值来获得辅助的布尔属性. (2认同)