首页 > 解决方案 > Mongo 通过 subdoc 数组的总和查找

问题描述

我试图在Stock集合中找到所有所有者股份的总和小于 100 的股票。这是我的架构。

const stockSchema = new mongoose.Schema({
  owners: [
    {
      owner: {
          type: Schema.Types.ObjectId,
          ref: "Owner"
      },
      shares: {
          type: Number,
          min: 0,
          max: 100
      }
    }
  ]
}

const Stock = mongoose.model("Stock", stockSchema);

我尝试使用aggregate,但它返回一个对集合中所有股票计算的单个对象,而不是每个股票份额总和的多个对象。

stockSchema.statics.getUnderfundedStocks = async () => {
  const result = await Stock.aggregate([
    { $unwind: "$owners" },
    { $group: { _id: null, shares: { $sum: "$owners.shares" } } },
    { $match: { shares: { $lt: 100 } } }
  ]);
  return result;
};

所以,而不是得到:

[ { _id: null, shares: 150 } ]getUnderfundedStocks,我希望得到:

[ { _id: null, shares: 90 }, { _id: null, shares: 60 } ].

我遇到过$expr,它看起来很有用,但是文档很少,并且不确定这是否是合适的路径。


编辑:一些文档示例:

/* 1 */
{
    "_id" : ObjectId("5ea699fb201db57b8e4e2e8a"),
    "owners" : [ 
        {
            "owner" : ObjectId("5ea62a94ccb1b974d40a2c72"),
            "shares" : 85
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5ea699fb201db57b8e4e2e1e"),
    "owners" : [ 
        {
            "owner" : ObjectId("5ea62a94ccb1b974d40a2c72"),
            "shares" : 20
        }, 
        {
            "owner" : ObjectId("5ea62a94ccb1b974d40a2c73"),
            "shares" : 50
        }, 
        {
            "owner" : ObjectId("5ea62a94ccb1b974d40a2c74"),
            "shares" : 30
        }
    ]
}

我想返回一个仅包含文档 #1 的数组。

标签: javascriptmongodbmongooseaggregation-framework

解决方案


你不需要在$group这里使用。只需$project$sum运算符一起使用。

db.collection.aggregate([
  { "$project": {
    "shares": { "$sum": "$owners.shares" }   
  }},
  { "$match": { "shares": { "$lt": 100 } } }
])

甚至你不需要在这里使用聚合

db.collection.find({
  "$expr": { "$lt": [{ "$sum": "$owners.shares" }, 100] }
})

Mongo游乐场


推荐阅读