João Otero
João Otero

Reputation: 998

Mongoose: MongoError: >1 field while trying to project out $elemMatch

I'm trying to project out only the matched element of an array, in the updated version. But I'm getting the error: "MongoError: >1 field in obj: { _id: 0, lotes.$: 1 }"

If I remove 'new: true', it works. But then I have the doc before the update. And I would really like the updated version.

What's wrong? How can I fix it?

The Offer doc is something like:

 {
      _id
      series: [ Serie ]
    }

Serie structure is something like:

{
  _id
  public.available: Number
  public.expDate: Date
}

I'm using Mongoose:

        var query = {
            '_id': offerId, 
            'series': { 
                $elemMatch: {
                    '_id': serieId,
                    'public.available': {$gt:0},
                    'public.expDate': {$gt: now}
                }
            }
        };
        var update = { 
            $inc: { 'series.$.public.available' : -1 }
        };
        var options = { // project out just the element found, updated
            new:true,
            select: {
              '_id': 0,
              'series.$': 1 
            }
        };

        Offers.findOneAndUpdate(query, update, options)
        .then( element => {
             ...
        }

Upvotes: 1

Views: 4205

Answers (2)

to240
to240

Reputation: 381

For anyone else experiencing this error, it is also the most common error when trying to perform an illegal action such as trying to update a database element inside of a findOne request.

Making sure your request is correct, such as findOneAndUpdate should be your first port of call when you get this error.

Upvotes: 4

João Otero
João Otero

Reputation: 998

As Anthony Winzlet pointed out in the links, there seems to be an issue with Mongoose, in which if you use 'new:true', you can't project out the $elemMatch.

So my solution was to keep using 'new:true' only, without projections. And reduce the array later on to get the $elemMatch:

.then( (result) => {
  var aux = result.series.reduce((acu, serie, index) => {
    if (serie._id == req.params.serieId) return index;
  });
  var element = result.series[aux];
}

Upvotes: 2

Related Questions