Home > Mobile >  Mongoose aggregate returning possible error/metadata, no clear error or response given
Mongoose aggregate returning possible error/metadata, no clear error or response given

Time:06-16

I'm trying to compile data from 2 collections on the backend before passing to the front to render a chart. One of the collections has different property names for the dates involved and both need to compile the hours. I have an aggregate pipeline working perfect on a single collection, but I figure it should be possible to run the pipeline on both and return a single array to pass to the front. However, the response I keep getting is what I assume is an error message:

{
    "ok": 0,
    "code": 40323,
    "codeName": "Location40323",
    "$clusterTime": {
        "clusterTime": {
            "$timestamp": "7107767560271036417"
        },
        "signature": {
            "hash": "35RndgTpiJ5STtcwh8bACLC7GRM=",
            "keyId": {
                "low": 178,
                "high": 1645023840,
                "unsigned": false
            }
        }
    },
    "operationTime": {
        "$timestamp": "7107767551681101827"
    }
}

but the server stays running and no other message/error is given. I've been messing with how I approach the pipeline but get the same result. I'm still learning mongodb/mongoose (and coding in general) so I'm sure theres something I'm doing wrong, but from the different threads/articles I've read I'm not finding the issue.

There are 3 collections involved- the User, TimeBrackets, and Visits, and the latter 2 are tied to the user by a ref: on the _id. Any help would be great.

Heres the pipeline:

    let isStart = req.body.isStart
    let isEnd = req.body.isEnd
    let userId = mongoose.Types.ObjectId(req.params.id)

  User.aggregate()
    .match({ user: userId })
    .lookup({
        from: "visits",
        as: "visits",
        let: [ 
            {visitStart: 'visits.visitStart'},
            {visitEnd: 'visits.visitEnd'}

        ],
        pipeline: [
            {
                $match: {
                    $and: [
                        { user: userId },
                        {visitStart: {$gte: new Date(isStart)}},
                        {visitEnd: {$lte: new Date(isEnd)}}
                    ]
                },
                $group: {
                    _id: { $dateToString: { date: "$visitEnd", format: "%m-%d-%Y" }},
                    hours: {
                        $sum: "$totalHours"
                    }
                }
            }
        ]
    }).unwind({ path: "visits", preserveNullAndEmptyArrays: true})
    .lookup({
        from: "timebrackets",
        as: "brackets",
        let: { hours: '$timebrackets.entries.hours'},
        pipeline: [
            {
                $match: {
                    $and: [
                        {user: userId},
                        {date: {$gte: new Date(isStart)}},
                        {date: {$lte: new Date(isEnd)}}
                    ]
                },
                $group: {
                    _id: { $dateToString: { date: "$date", format: "%m-%d-%Y"}},
                    hours: {
                        $sum: "$hours"
                    }
                }
            }
        ]
    }).unwind({ path: "brackets", preserveNullAndEmptyArrays: true})
    .project({
        _id: 0,
        date: "$_id",
        brackets: 1,
        visits: 1

    })
    .sort({ date: 'asc'})
    .exec((err, result) => {
       if (err) {
           res.send(err);
       } else {
           res.json(result);
       }
    });

UPDATE so the actual error message is: A pipeline stage specification object must contain exactly one field. I've looked over the stages and unless I'm missing something, I think my syntax is correct with where the {} are placed...

CodePudding user response:

So ultimately it came down to syntax, the error: A pipeline stage specification object must contain exactly one field, seems to generally infer that somewhere the {} are off. I had kept trying to wrap the lookup sub-pipelines in {}, but was forgetting to remove the initial {} set within the pipeline array. So essentially I was setting it as :

pipeline: [
            { <-- this being the error
              {$match: ...}
              {$group: ...}
  • Related