mongodb insert data into the array of objects and update it

二次信任 提交于 2020-03-05 03:01:06

问题


I need to make a vote, it looks like an array of objects, look like the user’s ID and the value that he set.

If the user has already voted, but changed his value, you need to change the value of the rate in the array of objects for this user.

I need to make an array of objects into which data will be inserted like this {rate: 3, user: "asdr2r24f2f42f24"} and if the user has already voted in this array, then you need to change the value rate of the given user

I already tried to do something, but it seems to me you can write something better, can you help?

JSON https://jsoneditoronline.org/?id=442f1dae0b2d4997ac69d44614e55aa6

 router.post('/rating', (req, res) => {
  console.log(req.body)
  // { id: 'f58482b1-ae3a-4d8a-b53b-ede80fe1e225',
  //   rating: 5,
  //   user: '5e094d988ddbe02020e13879' }

  Habalka.find({
    _id: req.body.id
  })
    .then(habalka => {

      // here I need to check whether the user has already voted or not, and from this whether to add an object with it or update the number
      Habalka.updateOne(
        {_id: req.body.id},
        {$push: {rating: {rate: req.body.rating, user: req.body.user}}}
      )
        .then(e => {
          console.log(e)
        })
    });
});

Schema

 const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const HabalkaSchema = new Schema({
  _id: {
    type: String
  },
  bio: {
    firstname: String,
    lastname: String,
    middlename: String,
    company: String
  },
  rating: [

  ],
  files: [
    {
      _id: {
        type: String
      },
      destination: {
        type: String
      },
      filename: {
        type: String
      },
      path: {
        type: String
      },
      folder: {
        type: String
      },
      info: {
        size: {
          type: Number
        },
        mimetype: {
          type: String
        },
        encoding: {
          type: String
        },
        originalname: {
          type: String
        },
        fieldname: {
          type: String
        },
      },
      date: {
        type: Date,
        default: Date.now
      },
      bio: {
        type: Object
      },
      userId: String,
      guessId: {},
    }
  ],
  date: {
    type: Date,
    default: Date.now
  }
});
module.exports = Habalka = mongoose.model('habalka', HabalkaSchema);

回答1:


This is an aggregation query which inserts a new user or updates the rating of existing user in the rating array: The req.body.id, req.body.user and req.body.rating are set as follows for the example code:

var ID = 1, INPUT_USER = "new user", INPUT_RATE = 5;

const matchStage = { $match: { _id: ID } };
const facetStage = {
  $facet: {
      new_user: [
        { $match: { "rating.user": { $not: { $eq: INPUT_USER } } } },
        { $addFields: { rating: { $concatArrays: [ "$rating", [ { user: "new user", rate: INPUT_RATE } ] ] } } },
      ],
      user: [   
        { $match: { "rating.user": INPUT_USER } },
        { $addFields: { 
               rating: {
                   $map: { 
                       input: "$rating",
                       as: "r",
                       in: {
                       $cond: [ { $eq: [ "$$r.user", INPUT_USER ] },
                                { user: "$$r.user", rate: { $add: [ "$$r.rate", INPUT_RATE ] } },
                                "$$r"
                              ]
                       }
                   }
               }
        } }
      ]
  }
};
const projectStage = { 
     $project: { 
         result: { $arrayElemAt: [ { $concatArrays: [ "$user", "$new_user" ] }, 0 ] }  
     }
};

const queryPipeline = [
    matchStage,
    facetStage,
    projectStage
];

// Run the aggregation query and get the modified document
// after applying the user and rate data in the rating array.
// The result of the aggregation is used to update the collection.
col.aggregate(queryPipeline).toArray( ( err, docs ) => {

    console.log("Aggregation output:");
    console.log( JSON.stringify( docs[0] ) );

    // Update the aggregate result to the collection.
    col.updateOne( { _id: docs[0].result._id },
                   { $set: { rating: docs[0].result.rating } }, 
                   ( err, updateResult ) => {
                       console.log( 'Updated count: ', updateResult.matchedCount );
                    }
     );

     callback(docs);
} );

Example collection document:

{ "_id" : 1, "rating" : [ { "user" : "user1", "rate" : 2 } ] }

If the input is var ID = 1, INPUT_USER = "new user", INPUT_RATE = 5; the updated document will be:

{ "_id" : 1, "rating" : [ { "user" : "user1", "rate" : 2 }, { "user" : "new user", "rate" : 5 } ] }

If the input is var ID = 1, INPUT_USER = "user1", INPUT_RATE = 5; the updated document will be:

{ "_id" : 1, "rating" : [ { "user" : "user1", "rate" : 7 } ] }


来源:https://stackoverflow.com/questions/59675838/mongodb-insert-data-into-the-array-of-objects-and-update-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!