MongoDB - 在两个集合之间聚合数据

时间:2018-01-09 06:16:50

标签: mongodb fullcalendar aggregation-framework mean-stack

我的应用程序是使用完整日历API的预订系统。日历包含卖家和客户,这些卖家和客户被路由以查看相同的日历并查看相同的事件。卖方在日历上创建资源,客户可以看到相同的资源并在他的最后预订。

我的目标:当客户进行预订时,我想查看卖家的收藏品,了解当前预订所包含的 容量 。如果容量小于或等于资源的预订数组内的预订数量,则客户无法进一步保留该特定预订。

我做了一些研究,我试图遵循这个例子: Mongodb aggregation with 2 collections

由于我从未在mongoDB中进行聚合,因此无法理解如何正确查询数据。

我的MEAN应用程序中有两个集合:

售票:

var bookingSchema = mongoose.Schema({

    userNumber:             { type: Number, required: false },
    resourceNumber:         { type: Number, required: true },
    startDateTime:          { type: Date, required: false, default: Date },
    endDateTime:            { type: Date, required: false, default: Date },
    description:            { type: String, default: false },
    title:                  { type: String, required: true },
    className:              { type: String, required: false},
    bookingIdRef:           { type: String, required: false}
    });

资源:

var resourceSchema = mongoose.Schema({

    resourceNumber:         { type: Number, required: true }, //dance studio 1 = resource number
    userNumber:             { type: Number, required: true },
    title:                  { type: String, required: true },
    numberOfBookings:       { type: Number, required: true },
    numberOfBookingExists:  { type: Boolean, default: false},
    description:            { type: String, default: false },
    booking:
        [
            {
                //_id: Schema.Types.ObjectId,
                //each array contains _id which we can use instead of slotId // _id slot
                capacityPerBooking:  { type: Number, required: false},
                startDateTime:       { type: Date, required: false, default: Date },
                endDateTime:         { type: Date, required: false, default: Date },
                className:           { type: String, required: false}
            }
        ]

    });

创建每个资源时,资源内booking数组内的每个预订都会获得capacityPerBooking。在客户端,当客户点击日历上的某个活动并点击保留时,它会调用POST请求,我会在其中执行聚合。这是我有点困惑的部分。

这是服务代码:

var Booking = require('./booking.db.schema.js');
var Resource = require('../resource/resource.db.schema');

module.exports = class BookingService {

    //========================================================
    // create
    //========================================================
    create(req, res, sourceBooking, callback) {
        console.log('+ bookingService.create(%s)', JSON.stringify(sourceBooking));

        //create a resource
        var targetBooking = new Booking({
                userNumber:             req.user.userNumber,    //Samples always belong to the user who created them
                resourceNumber:         sourceBooking.resourceNumber,
                startDateTime:          sourceBooking.startDateTime,
                endDateTime:            sourceBooking.endDateTime,
                title:                  sourceBooking.title,
                description:            sourceBooking.description,
                className:              sourceBooking.className,
                bookingIdRef:           sourceBooking._id
            });

        var pipeline = [
            {
                "$match": { "resourceNumber" : sourceBooking.resourceNumber},
                //"$group": { _id: null, capacityPerBooking: { $lte: sourceBooking.capacityPerBooking } }
            }
        ];

        console.log('pipeline: ' + JSON.stringify(pipeline, null, 2));

        Booking.aggregate(pipeline, function(err, results) {
            if (err)
            {
                throw err, console.log('aggregation error: ' + err);
            }
            else
            {
                console.log(JSON.stringify(results, undefined, 4));
            }

        });

        Booking.find({"resourceNumber" : sourceBooking.resourceNumber}).lean().exec(function (err, objs){
            var ids = objs.map(function (o) { return o.coll_id; }),
                pipeline = [
                    {
                        "$match": { "_id" : { "$in": ids },
                            "capacityPerBooking": { "$lte": "capacityPerBooking" } }
                    },
                    {
                        "$group": {
                            "_id": null,

                        }
                    }
                ];

            console.log('pipeline: ' + JSON.stringify(pipeline, null, 2));
            Resource.aggregate(pipeline, function(err, results) {
                    if (err)
                    {
                        throw console.log('++aggregation error++ : ' + err);

                    }
                    else
                    {
                        console.log(JSON.stringify(results, undefined, 4));
                    }

                });
        });
        var tempArray = [];
        Booking.aggregate([
            { "$lookup": {
                "from": "Resource",
                "localField": "resourceNumber",
                "foreignField": "resourceNumber",
                "as": tempArray
            }},
            { "$match": { "Resource.0": { "$resourceNumber": sourceBooking.resourceNumber } } }
        ])

        console.log('tempArray: ' + JSON.stringify(tempArray, null, 2));


        targetBooking.save(function(err, newBooking) {
            if (err) {
                console.log(err);
                callback(err, null);
            } else {
                callback(null, newBooking);
            }
        });
}

注意:soureBooking包含有关通过POST传递的预订的数据。

我知道我的步骤必须如下:

    1。查看`capacityPerBooking`
的`resource`集合
    2。匹配`Booking`中的`resourceNumber`到`Resource.booking []`
    3。比较** resourceNumber **的预订数量与`capacity`
    4。如果$ lte创建预订,否则抛出错误

我的问题是,我该如何设置这样的东西。我从来没有在mongoDB中进行聚合,并且在他们的网站上关注文档时遇到了一些麻烦。任何建议或帮助将不胜感激!

0 个答案:

没有答案