Mongoose计算嵌入式文档数组中的某些元素

时间:2016-10-08 17:43:31

标签: node.js mongodb mongoose aggregation-framework mongodb-aggregation

我正在使用mongoose 4.6.3

我有以下架构:

var mongoose = require('mongoose');
var User = require('./User');

var TicketSchema = new mongoose.Schema({
    user : { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
},
{
    timestamps: true
});

var DrawSchema = new mongoose.Schema({
  ...
  max_ticket_per_user : { type : Number, required: true },
  tickets: [TicketSchema]
});

module.exports = mongoose.model('Draw', DrawSchema);

如何在Draw的票证(DrawSchema中的票证字段)中计算某个User ObjectId(TicketSchema中的用户字段)的嵌入文档? 我想计算一次用户的门票。

更改我的架构设计会更好吗?

由于

2 个答案:

答案 0 :(得分:4)

您可以使用聚合框架利用 $filter $size 运算符来获取包含与用户匹配的元素的已过滤数组id和它的大小分别随后给你计数。

对于单次绘制,请考虑添加 $match 管道运算符作为初始步骤,使用_id查询过滤集合中的文档。

考虑运行以下聚合管道以获得所需的结果:

Draw.aggregate([
    { "$match": { "_id": drawId } },
    {
        "$project": {
            "ticketsCount": {
                "$size": {
                    "$filter": {
                        "input": "$tickets",
                        "as": "item",
                        "cond": { "$eq": [ "$$item.user", userId ] }
                    }
                }
            }
        }
    }
]).exec(function(err, result) {
    console.log(result);
});

答案 1 :(得分:1)

您可以像任何其他查询对象一样传递.count()深度参数:

Draw.count({'tickets.user._id' : userId}, console.log);

确保userId变量是ObjectId。如果它是一个字符串,请执行以下操作:

const ObjectId = require('mongoose').Types.ObjectId;
let userId = new ObjectId(incomingStringId);