RayOfHope
RayOfHope

Reputation: 15

Error:Can't canonicalize query: BadValue Unsupported projection option

User Schema

var UserSchema = new Schema({

    name: String,
    username: { type: String, required: true, index: { unique: true }},
    password: { type: String, required: true, select: false},
    favouriteid:[{eventid:String}]

});

Event Schema

var EventSchema=new Schema({
    name:String,
    location:{ type:String },
    description:{type:String  },
    price: String,
    rating: {
        value: String,
        count: {type: String, default: 10},
        userrating: [{
            uservalue: String,
            userid: String
        }]
    },
    imageurl:[String],
    userimageurl:[String],


    reviews:[{ userid:String,
        username: String,
                comment:String}]

});

POST METHOD to push the value of userid and uservalue in Event Schema.

api.post('/rateevent', function (req, res) {

        var userid = req.body.userid;
        var uservalue = req.body.uservalue;
        var eventid = req.body.eventid;

        Event.findById({_id: eventid},
            {$push: {rating: {userrating: {uservalue: uservalue, userid: userid}}}},
            {upsert: true},
            function (err, events) {
                if (err) {
                    res.send(err);
                    return;
                }
                else {
                    calculaterating(events);
                }
            });

        function calculaterating(event) {

            event.rating.count++;
            event.rating.value = (event.rating.value * (event.rating.count - 1) + uservalue) / event.rating.count;


            res.json("rating updated");


        }


    });

It is showing the following error:

{
  "name": "MongoError",
  "message": "Can't canonicalize query: BadValue Unsupported projection option: $push: { rating: { userrating: { uservalue: \"5\", userid: \"56593f3657e27af8245735d7\" } } }",
  "$err": "Can't canonicalize query: BadValue Unsupported projection option: $push: { rating: { userrating: { uservalue: \"5\", userid: \"56593f3657e27af8245735d7\" } } }",
  "code": 17287
}

Is the post method not correct? I have seen other mongodb documents but not able to find this type of thing. I am new to node js. Help me.

Upvotes: 1

Views: 2672

Answers (2)

Shashwat Gupta
Shashwat Gupta

Reputation: 5272

in MY case

i was using the wrong method like below i was updating the record by findOne , that can`t be possible , in my case , thats why issues occurs

Solution: if you want to update the record , use .update() method, and if you want to find records , then you can use .find() , .findOne() , don`t mismatch

domain.Cart.findOne({
                                        UserId: req.body.UserId,
                                        shopId: req.body.shopId,
                                    },
                                        { $addToSet: { "productDetails": _productDetails } }
                                    ).exec(function (err, results) {
                                        console.log(err, results)
                                        callback(null, {
                                            result: results,
                                            msg: "productCount has been updated"
                                        })

                                    })

Upvotes: 0

Sarath Nair
Sarath Nair

Reputation: 2868

It should be Event.update instead of Event.findById, Also your push operation looks wrong. It should be like this:

Event.findOneAndUpdate(
        {_id: eventid},
        {$push: {'rating.userrating': {uservalue: uservalue, userid: userid}}},
        {new: true},
        function (err, events) {
            if (err) {
                res.send(err);
                return;
            }
            else {
                if(events.length > 0){
                    calculaterating(events);
                }
                else {
                    res.json({msg: "Nothing to update"});
                }
            }
        });

function calculaterating(event) {
  event = event[0]; //get the object from array
  event.rating.count++;
  event.rating.value = (event.rating.value * (event.rating.count - 1) + uservalue) / event.rating.count;
  Event.update(
    {_id: eventid},
    {$set: {
      'rating.count': event.rating.count,
      'rating.value': event.rating.value
    }},
    function(err, response){
      if (err) {
        res.send(err);
        return;
      }
      else {
        res.json({msg: "rating updated"});
      }
    });
}

In events variable you will get the document that was updated in the new state. If you had passed {new: false} you will get the document as it was before the update.

Upvotes: 2

Related Questions