首页 > 解决方案 > 来自谷歌表格的补丁请求覆盖以前的帖子请求

问题描述

我正在将 12 个单元格值从谷歌表发送到 mongodb 数据库。我这样做的原因是因为我想连接 12 个单元格并对数据进行一些转换,然后将其输出到前端。我也在这样做,因为工作表将每个单元格限制为 50k 个字符,并且我每次需要将大约 500k 个字符发送到数据库。我最初的假设是我需要在 MondoDB 中创建 1 条包含所有 12 个单元格值的记录(可能另一种方法是在一个集合中发布 12 个单独的记录)。所以我这样做的方式是做一个 POST 请求,然后在最初发布的记录上可能有 11 个 PATCH 请求,所有这些请求都在谷歌表格内的一个谷歌脚本函数中。我遇到的问题是我不确定如何形成模型&路线&请求。每次我做一个补丁(如下所示)时,它都会覆盖以前的 POST 数据。我希望它只更新通过 PATCH 请求发送的 JSON 部分。目前 PATCH 请求正在将所有其他记录更改为null并删除以前的 POST 数据。我知道有一种方法可以只修补集合中的特定记录,但是如何修补我没有得到的集合中 json 的特定部分。

特快专递路线:

router.post('/', async (req,res) => {
  const post = new Post({
    title: req.body.title,
    en1: req.body.en1,
    en2: req.body.en2,
    en3: req.body.en3,
    en4: req.body.en4,
    fr1: req.body.fr1,
    fr2: req.body.fr2,
    fr3: req.body.fr3,
    fr4: req.body.fr4,
    de1: req.body.de1,
    de2: req.body.de2,
    de3: req.body.de3,
    de4: req.body.de4
  });

  try {
    const savedPost = await post.save();
    res.json(savedPost);
  } catch (err) {
    res.json({ message: err })
  }
})

快速更新路线:

router.patch('/:postId', async (req,res) => {
  try {
    const updatedPost = await Post.updateOne(
      { title:req.params.postId }, 
      { $set: {
        title: req.body.title,
        en1: req.body.en1,
        en2: req.body.en2,
        en3: req.body.en3,
        en4: req.body.en4,
        fr1: req.body.fr1,
        fr2: req.body.fr2,
        fr3: req.body.fr3,
        fr4: req.body.fr4,
        de1: req.body.de1,
        de2: req.body.de2,
        de3: req.body.de3,
        de4: req.body.de4 
      } }
    )
    res.json(updatedPost)
  }catch(err){
    res.json({ message: err })
  }
})

猫鼬型号:

const mongoose = require('mongoose')

const PostSchema = mongoose.Schema({
  title: {
    type: String,
    required: false
  },
  en1: {
    type: String,
    required: false
  },
  en2: {
    type: String,
    required: false
  },
  en3: {
    type: String,
    required: false
  },
  en4: {
    type: String,
    required: false
  },
  fr1: {
    type: String,
    required: false
  },
  fr2: {
    type: String,
    required: false
  },
  fr3: {
    type: String,
    required: false
  },
  fr4: {
    type: String,
    required: false
  },
  de1: {
    type: String,
    required: false
  },
  de2: {
    type: String,
    required: false
  },
  de3: {
    type: String,
    required: false
  },
  de4: {
    type: String,
    required: false
  },
  date: {
    type: Date,
    default: Date.now
  }
})

module.exports = mongoose.model('Posts', PostSchema)

来自表格的 GOOGLE SCRIPT POST 请求(目前只有一个补丁请求):

function sendInfoToApi() {
  const randomId = Math.random()*100000000000000000;

  var en1 = SpreadsheetApp.getActive().getSheetByName("Final").getRange('A3').getValues()[0][0];
  var en2 = SpreadsheetApp.getActive().getSheetByName("Final").getRange('A4').getValues()[0][0];

  // 11111 POST REQUEST //
  var data1 = {
    "title": randomId,
    "en1": en1
  }
  var payload1 = JSON.stringify(data1)  
  var url1 = 'https://ag-sheets-api.herokuapp.com/posts';
  var fetchParameters1 = {
      'method': 'post',
      'contentType': 'application/json', 
      'payload' : payload1,
      'muteHttpExceptions' : false
  };
  try {
      var response = UrlFetchApp.fetch(url1, fetchParameters1);
      } catch(e){
        Logger.log(e)
  }

  // 22222 PATCH REQUEST //
  var data2 = {
    "title": randomId,
    "en2": en2
  }
  var payload2 = JSON.stringify(data2)  
  var url2 = `https://ag-sheets-api.herokuapp.com/posts/${randomId}`;
  var fetchParameters2 = {
      'method': 'patch',
      'contentType': 'application/json', 
      'payload' : payload2,
      'muteHttpExceptions' : false
  };
  try {
      var response = UrlFetchApp.fetch(url2, fetchParameters2);
      } catch(e){
        Logger.log(e)
  }
}

MongoDB中的结果记录:

  _id:60072da8c52278001791e22e
title:"42612001948065650"
en1:null
date:2021-01-19T19:06:16.052+00:00
__v:0
de1:null
de2:null
de3:null
de4:null
en2:"<div class="qw">
        <div class="qe" data-country="gq.svg"> <p cla..."
en3:null
en4:null
fr1:null
fr2:null
fr3:null
fr4:null

在这里您可以看到 PATCH 请求如何将 en1 中的数据覆盖为 null,如何使其仅更新 en2,而跳过其他值?

标签: javascriptnode.jsmongodbexpressgoogle-apps-script

解决方案


问题是您检索所有参数,即使它们在请求中不存在。因此,返回null所有属性。

en1: req.body.en1,
en2: req.body.en2,
en3: req.body.en3,
en4: req.body.en4,
fr1: req.body.fr1,
fr2: req.body.fr2,
fr3: req.body.fr3,
fr4: req.body.fr4,
de1: req.body.de1,
de2: req.body.de2,
de3: req.body.de3,
de4: req.body.de4 

您只发送了其中一个,而不是全部。您应该循环请求密钥和那些唯一的。

router.patch('/:postId', async (req,res) => {
  try {
    const updatedObj = {};
    for(let i in req.body) {
        if(req.body.hasOwnProperty(i) && i.match(/^(title|(en|fr|de)[1-4])$/)) updatedObj[i] = req.body[i];
    }
    const updatedPost = await Post.updateOne(
      { title:req.params.postId }, 
      { $set: updatedObj }
    )
    res.json(updatedPost)
  }catch(err){
    res.json({ message: err })
  }
})

我向发送的属性添加了一些正则表达式验证,以避免设置您不希望 Web 请求更新的其他键。如果请求受信任,您可以将其删除。


推荐阅读