【问题标题】:Mongo find by sum of subdoc arrayMongo 通过 subdoc 数组的总和查找
【发布时间】:2020-08-10 20:40:38
【问题描述】:

我正在尝试在 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 的数组。

【问题讨论】:

    标签: javascript mongodb mongoose aggregation-framework


    【解决方案1】:

    您不需要在这里使用$group。只需将$project$sum 运算符一起使用即可。

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

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

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

    MongoPlayground

    【讨论】:

    • 您的第二个解决方案更可取,因为它返回原始模式,而不是像第一个解决方案那样添加新的shares 属性,这在与同一集合的其他文档组合时很麻烦。太棒了!
    猜你喜欢
    • 2018-04-29
    • 2021-09-17
    • 1970-01-01
    • 2012-11-11
    • 2014-10-16
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 2017-05-31
    相关资源
    最近更新 更多