MongoDB (Mon goose) `findByIdAndDelete` не удаляется (тестирование с почтальоном) - PullRequest
0 голосов
/ 25 апреля 2020

Мой код Mon goose содержится в отдельном файле model.js, а код Express для обработки запросов http находится в app.js. Я просто практикую создание API-интерфейсов и тестирую их на Postman для воображаемого вики-сайта. API, который я пытаюсь заставить работать, - это удаление одной статьи. (Примечание: для краткости я включил только рассматриваемый код, то есть app.delete('/articles/:id' .... из app.js и метод stati c, который он вызывает из model.js - deleteOneArticleFromDB(articleID)

app.js:

const express = require('express');
const bodyParser = require('body-parser');
const model = require('./model');

const app = express();

app.use(bodyParser.urlencoded({ extended: true }));

app.delete('/articles/:id', async (req, res) => {
    const articleID = req.params.id;
    console.log(`req.params.id: ${req.params.id}`);
    try {
        const response = await model.DBUtility.deleteOneArticleFromDB(articleID);
        res.status(200).json({message: response, app: 'wiki-api'});
    } catch (err) {
        res.json({message: err, app: 'wiki-api'});
    }
});

const port = 3000;
app.listen(port, () => {
    console.log(`Server started on port ${port}`);
});

model.js:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/wikiDB', {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false });

const articleSchema = new mongoose.Schema({
    title: String,
    content: String
});

const Article = mongoose.model('Article', articleSchema);

class DBUtility {

    static deleteOneArticleFromDB(articleID) {
        return new Promise((resolve, reject) => {
            Article.findByIdAndDelete(articleID, (err) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(`Deleted article ${articleID} successfully`);
                }
            });
        });
    }
}

exports.DBUtility = DBUtility;

В моей базе данных 5 статей (5 документов):

{
    "_id" : "5c139771d79ac8eac11e754a",
    "title" : "API",
    "content" : "API stands for Application Programming Interface. It is a set of subroutine definitions, communication protocols, and tools for building software. In general terms, it is a set of clearly defined methods of communication among various components. A good API makes it easier to develop a computer program by providing all the building blocks, which are then put together by the programmer."
}

/* 2 */
{
    "_id" : "5c1398aad79ac8eac11e7561",
    "title" : "Bootstrap",
    "content" : "This is a framework developed by Twitter that contains pre-made front-end templates for web design"
}

/* 3 */
{
    "_id" : "5c1398ecd79ac8eac11e7567",
    "title" : "DOM",
    "content" : "The Document Object Model is like an API for interacting with our HTML"
}

/* 4 */
{
    "_id" : "5ea2c188fa57aa1b6453eda5",
    "title" : "Node JS",
    "content" : "Node.js is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside of a web browser. Node.js lets developers use JavaScript to write command line tools and for server-side scripting—running scripts server-side to produce dynamic web page content before the page is sent to the user's web browser. Consequently, Node.js represents a \"JavaScript everywhere\" paradigm,[6] unifying web-application development around a single programming language, rather than different languages for server- and client-side scripts.",
    "__v" : 0
}

/* 5 */
{
    "_id" : "5ea2d5304e19b11e0013a86a",
    "title" : "EJS",
    "content" : "EJS is a simple templating language that lets you generate HTML markup with plain JavaScript. No religiousness about how to organize things. No reinvention of iteration and control-flow. It's just plain JavaScript",
    "__v" : 0
}

I ' Я пытаюсь удалить последнюю статью (документ) с заголовком EJS. Поэтому в Почтальоне я выполняю http-запрос следующим образом:

enter image description here

Как вы видите, я получаю ответ об успехе. Однако, когда я проверяю свою базу данных, документ все еще там (я несколько раз нажал refre sh и также проверил его с запросом GET, чтобы вернуть все статьи, которые показали, что статья еще там): enter image description here

Вот вывод терминала:

[nodemon] starting `node app.js`
Server started on port 3000
req.params.id: 5ea2d5304e19b11e0013a86a

Я был на этом в течение двух дней. Я проверил все предыдущие SO посты с похожими заголовками, но я не вижу ни одной, которая относится к моей проблеме. Я не понимаю, где я иду не так !! Любая помощь будет очень признательна .

ОБНОВЛЕНИЕ

В соответствии с решением, приведенным ниже Мохаммедом Йусри, я понял, что добавил поле _id вручную, используя строки, так как я следовал вдоль к руководство. Следовательно, не позволяя MongoDB создавать поле _id вместо ObjectId. Поэтому мое поле _id было типа String, а не ObjectId. Поэтому для решения этой проблемы я удалил все документы из базы данных и заново добавил их, используя POSTMAN с созданным мною методом POST - для создания / добавления нового документа статьи в базу данных, предоставляя только поля title и content в теле запроса. Следовательно, позволяя MongoDB создавать поле _id вместо каждого документа статьи. Теперь в базе данных поле _id имеет тип ObjectId. Это до сих пор не решило мою проблему полностью, но это еще один шаг вперед. Все еще работаем над достижением решения. Пожалуйста, обратитесь к обсуждению ниже в разделе решения.

enter image description here

Ответы [ 2 ]

2 голосов
/ 25 апреля 2020

В MongoDB свойство _id имеет тип ObjectId.
У меня была такая же проблема, и я исправил ее, передав вместо ObjectId.

Вы пробовали следующее?

const Mongoose = require('mongoose');
const articleId = Mongoose.Types.ObjectId(req.params.id);
1 голос
/ 25 апреля 2020

1 - может быть ваша mongoose версия не поддерживает findByIdAndDelete

, попробуйте findByIdAndRemove вместо

2 - вы можете передать идентификатор этому методу в виде строки или как objectId

убедитесь, что вы передаете правильный идентификатор без пробелов

const articleID = req.params.id.toString().trim(); // trim will remove any spaces before or after the id

Обновите

в соответствии с этим изображением

enter image description here

кажется, что вы вставили свои данные вручную, и эти данные содержали _id в виде строки, так как тип _id является здесь строкой, как вы можете видеть на этом изображении

Я предлагаю вам разрешить MongoDB самому установить _id

Если вы можете изменить тип _id на ObjectId

или Если вы не можете изменить тип _id, вы можете сделать резервную копию своих статей, затем удалить все эти статьи вручную и добавить их снова без _id, позволить mongoDB установить этот _id и повторить попытку кода

надеюсь, что это может решить проблему



Обновление 2

После проверки кодов в github, я kno w причина, по которой вы получили это странное поведение

1 - у вас есть маршрут app.route('/articles/:articleTitle'), определенный до маршрута app.delete('/articles/:id'

, поэтому, когда вы пытаетесь удалить какую-то статью, передав идентификатор , nodeJS и express передаст его на первый соответствующий маршрут, так как он не знает отправленный вами params, он ищет базу url в route, поэтому он имеет дело с первым маршрутом который соответствует url: '/articles/something', примите это как заголовок статьи

, затем вызовите метод deleteOneArticleByTitleFromDB

MongoDB затем ищет какую-нибудь статью с названием = id, который вы прошло, ничего не нашел, значит, не удаляет ни одной статьи

2 - Я предлагаю вам не определять некоторые маршруты с одинаковым базовым URL

, чтобы вы могли определить удаление по Id маршрут, подобный следующему

app.delete('/arti/cles/:id', async (req, res) => // note the slash inside articles word

или все, что вы хотите, кроме текущего

, тем самым вы избежите противоречия между маршрутами

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...