Mon go найти по сумме массива subdo c - PullRequest
1 голос
/ 27 апреля 2020

Я пытаюсь найти акции в коллекции 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.

1 Ответ

2 голосов
/ 27 апреля 2020

Вам не нужно использовать $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

...