【问题标题】:res.data Always Returning an Empty Arrayres.data 总是返回一个空数组
【发布时间】:2021-02-17 16:30:39
【问题描述】:

我正在创建一个 MERN 杂志 Web 应用程序,该应用程序向用户显示存储在 mongodb 中的文章。我有多个数据库,在 Mongo Atlas 上称为 userDB 和 articleDB。这些数据库位于单个集群中。问题是,在我的一个控制器 articleController.js 中,集合上的 find 方法总是返回一个空数组。这导致我的应用程序崩溃,因为它始终可以工作并且没有返回一个空数组,而是返回一个包含三个最新文章对象的数组,然后我开始将我的数据从本地 mongodb 转换到 Atlas。

这是我文章Controllers.js的一段代码sn-p:

const express = require('express');
const app = express();
const cors = require("cors");
let articleSchema = require('../models/article.model');
const mongoose = require("mongoose");

const conn = mongoose.createConnection("mongodb+srv://<username>:<password>@cluster0.c94ps.mongodb.net/articleDB?retryWrites=true&w=majority", { useNewUrlParser: true, useUnifiedTopology: true, dbName: "articleDB" });

const Article = conn.model('article', articleSchema); // update: this is where the problem was.
const fs = require("fs");
const path = require("path");

app.use(cors({
    origin: 'http://localhost:3000',
    credentials: true 
}));

app.use('/images', express.static(path.join(__dirname, '/images')));

exports.article_home_section_display_get = (req, res) => {
    const id = req.params.id;
    const firstLetter = id.charAt(0).toUpperCase();
    const restOfWord = id.substring(1, id.length);
    const fullWord = firstLetter + restOfWord;
    Article.find({article_section: fullWord}).sort({article_date: -1}).limit(3)
        .then(articles => {
            console.log(articles); //empty array
            console.log(`Found and sent over three of the latest ${fullWord} articles.`);
            res.send(articles);
        })
        .catch(err => {
            console.log(err);
        });
};

其中尖括号中的 usernamepassword 是我的实际用户名和密码。

会不会是在连接多个数据库时使用 mongoose.createConnection 连接到 mongo Atlas 实际上是不可能的?或者,我的应用程序根本没有连接到 Atlas,因为我忽略了某种错误?对了,Atlas上的数据库叫做articleDB,里面的集合是article

我已经为此苦苦挣扎了很长时间,当我做别人做的事情时,我无法弄清楚哪里出了问题。因此,任何帮助将不胜感激。

【问题讨论】:

    标签: node.js mongodb express mongoose mongodb-atlas


    【解决方案1】:

    mongoose.connect 放在不在控制器中的app.js 文件中,然后这样做

    const dbURI = "mongodb+srv://<username>:<password>@cluster0.c94ps.mongodb.net/articleDB?retryWrites=true&w=majority";
    mongoose.connect(dbURI,{useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false}).then((result) => {
      console.log('connected to db')
    }).catch((err) => console.log(err));
    

    创建一个 artilce.js 文件并像这样导出模型:

    const mongoose = require('mongoose');
    const Schema =mongoose.Schema;
    
    const articleSchema = new Schema({
    
    });
    
    const Article= mongoose.model('article', articleSchema);
    module.exports = Article;
    

    在控制器中需要文章

    const Article = require('./models/article'); // path of article.js file
    

    【讨论】:

    • 如果我这样做,我应该如何定义“文章”?
    • 另外,我可以为多个数据库执行此操作吗?
    • 如果你想在控制器中使用 mognoose.connection 使用 .then .catch 来显示你连接正确
    • 如果你想连接到多个数据库,请检查这个问题stackoverflow.com/questions/19474712/…
    • 我已经按照你说的做了,它记录了“连接到数据库”,但它仍然返回一个空数组。如果我的收藏有数据,这怎么可能?实际上,我使用 Mongo Compass 从本地 mongodb 将数据导出并导入到 Atlas。这可能是问题吗?
    【解决方案2】:

    好的,经过一天的搜索,我终于找到了答案。问题出在:

    const Article = conn.model("article", articleSchema);
    

    第一个参数不正确,“article” 是表示数据库中集合名称的输入。这意味着 Mongoose 将查找名为 articles 的集合。这是因为在查找集合时,Mongoose 会将第一个参数转换为复数形式(如果您写“Article”之类的内容,则为小写形式)。

    但是,我的数据库名为 articleDB,而我在此数据库中的集合称为 article(集合名称不是复数!)。所以当Mongoose在我的数据库中查找集合时,将第一个参数"article"转换为articles时,就找不到了。因此,导致 res.data 返回一个空数组。

    要解决这个问题,您可以在 .model 函数中添加第三个参数。像这样,解决了我的问题:

    const Article = conn.model("article", articleSchema, "article");
    

    第三个参数 "article" 让 Mongoose 知道它不应该复数(并转换为小写)第一个参数。而是第三个参数让 Mongoose 知道集合的显式名称。

    在有三个参数的情况下,第一个参数的作用,我不太确定。但是,一旦您在数据库中明确定义集合的名称,第一个参数似乎是多余的。它可能就像一个占位符来区分两参数和三参数 .model 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-20
      • 2021-10-22
      • 2019-12-02
      • 2021-12-27
      相关资源
      最近更新 更多