繁体   English   中英

如何使用 $inc 增加 MongoDB 集合中的属性

[英]How to increment property in MongoDB collection using $inc

我有一个具有属性views的文章列表,每次用户单击文章标题时,我都想在数据库中增加该属性。 目前,当我这样做时没有任何反应。 为什么它不起作用,我如何在每次点击时增加该属性? 这是我的 React 部分:

  const incrementViews = (id) => {
        var item = posts.find(x => x._id === id);
        item.views += 1;
    }

      <div className="post-title">
          <Link to={`/post/${post._id}`}>
    <h2><a href="#" onClick={() => incrementViews(post._id)}>{post.title}</a>
       </h2>
        </Link>
 </div>

和我的 server.js:

// Requiring the dependencies
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
require('dotenv').config();
const mongoose = require('mongoose');
const PORT = process.env.PORT || 3001;
const BASE_URL = process.env.REACT_APP_BASE_URL;
console.log(BASE_URL)
const itemRoutes = express.Router();
let Comment = require('./comment.model');

app.use(cors());
app.use(bodyParser.json());

mongoose.connect(BASE_URL, { useNewUrlParser: true })

const connection = mongoose.connection;

connection.once('open', function () {
  console.log('Connection to MongoDB established succesfully!');
});

let collection = connection.collection("posts_with_tags_test");
collection.createIndex(
  {
    postContent: 'text',
    title: 'text'
  }
);


// Serve static assets
if (process.env.NODE_ENV === 'production') {
  app.use(express.static('build'));
}

itemRoutes.route('/').get(async (req, res) => {
  let collection = connection.collection("posts_with_tags_test");
  let response = await collection.find({})
    .toArray();
  res.send(response);
});


itemRoutes.route('/search').post(async (req, res) => {
  let result = await connection.collection("posts_with_tags_test").find({
    $text: {
      $search: req.body.searchString
    }
  }).toArray();
  res.send(result);
});


itemRoutes.route("increment/:id"").post(async (req, res) => {
  const { id } = req.params;
  collection.updateOne({ _id: id }, { $inc: { views: 1 } });
  return res.status(200).json({ msg: "OK" });
});

itemRoutes.route('/comments').get(async (req, res) => {
  let collection = connection.collection("comments");
  let response = await collection.find({})
    .toArray();
  res.send(response);
});


itemRoutes.route('/comments')
  .post((req, res) => {
    res.setHeader('Content-Type', 'application/json');
    let comment = new Comment(req.body);
    comment.save()
      .then(comment => {
        res.status(200).json({ comment })
      })
      .catch(err => {
        res.status(400).send('failed')
      })
  });


app.use('/', itemRoutes);
app.use('/comments', itemRoutes);
app.use('/search', itemRoutes);
app.use('/increment', itemRoutes);

app.listen(PORT, function () {
  console.log('Server is running on' + ' ' + PORT);
})

我认为前端和后端分别有两个问题。

  • 前端

    您应该将post变量用作 state 变量,以便在对post进行更改时重新渲染 then 组件。

  • 后端

    在您的代码中增加view没有问题。

    在这里,您需要返回成功状态。

function incrementViews仅增加前端的视图,从不向 API 发送任何数据。一种使其工作的方法如下:

  1. server.js
itemRoutes.route("/increment/:id").post(async (req, res) => {
  const { id } = req.params;
  collection.updateOne({ _id: id }, { $inc: { views: 1 } });
  return res.status(200).json({ msg: "OK" });
});
  1. 反应
const incrementViews = (id) => {
  // Assuming your API server is running on port 5000.
  fetch(`http://localhost:5000/increment/${id}`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
    },
  })
    .then((res) => res.json())
    .then(console.log)
    .catch(console.error);
};

更新

你得到 404 的原因是路由参数中缺少冒号:

// Notice the :id, colon is important.
itemRoutes.route("/increment/:id").post(async (req, res) => {
  const { id } = req.params;
  // ...
});

这是在 Glitch 上复制的演示 删除了数据库逻辑,只添加了一条响应消息。 我使用 Postman 测试了演示,它工作正常。

在对https://adaptive-sassy-legal.glitch.me/increment/123的 POST 请求中,应返回如下所示的响应。

{
  msg: "itemsRoute increment.",
  id: "123"
}

更新 2

我在之前的更新中忘记提及的另一件事是更新中间件。

// Use only `/increment` instead of `increment/:id`.
app.use("/increment", itemRoutes);

这是一个更新的演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM