【问题标题】:mongodb insert data into the array of objects and update itmongodb 将数据插入对象数组并更新它
【发布时间】:2020-04-27 18:13:02
【问题描述】:

我要投票,它看起来像一个对象数组,看起来像用户的 ID 和他设置的值。

如果用户已经投票,但改变了他的值,你需要改变这个用户的对象数组中的 rate 值。

我需要创建一个对象数组,数据将像这样插入其中 {rate: 3, user: "asdr2r24f2f42f24"} 并且如果用户已经在这个数组中投票,那么您需要更改值 rate给定的用户

我已经尝试过做一些事情,但在我看来你可以写得更好,你能帮忙吗?

JSONhttps://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)
        })
    });
});

架构

 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);

【问题讨论】:

    标签: node.js mongodb express mongoose


    【解决方案1】:

    这是一个聚合查询,它在rating 数组中插入一个新用户或更新现有用户的评分: 示例代码的req.body.idreq.body.userreq.body.rating设置如下:

    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);
    } );
    

    示例集合文档:

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

    如果输入是var ID = 1, INPUT_USER = "new user", INPUT_RATE = 5;,更新后的文档将是:

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

    如果输入是var ID = 1, INPUT_USER = "user1", INPUT_RATE = 5;,更新后的文档将是:

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

    【讨论】:

    • 谢谢,但是查询太难了,我试过了,报错 TypeError: cursor.next is not a function =(
    • 我更正了代码;它运行和更新正常。聚合查询看起来很复杂,但没有选择。您可以在程序中构建逻辑而不是聚合,但这也会是很多代码。
    • TypeError: Habalka.aggregate(...).toArray 不是函数
    • 我使用的是 MongoDB NodeJS driver APIs。如果它与您使用的代码不同,则代码将无法正常工作。
    猜你喜欢
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    相关资源
    最近更新 更多