通过_id的MongoDB Node.js deleteOne不能在ObjectId上运行 [英] MongoDB Node.js deleteOne via _id doesn't work on ObjectId

查看:159
本文介绍了通过_id的MongoDB Node.js deleteOne不能在ObjectId上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在mongo数据库包装器上编写测试(规范)并偶然发现这个奇怪的问题。

I'm trying to write test (spec) on a mongo DB wrapper and stumbled on this weird issue.

我的代码,构建在一个瘦的包装器之上mongodb,将 _id 作为字符串暴露给世界,但在与mongo交谈时使用(转换)它们到ObjectId。

My code, build on top of a thin wrapper of mongodb, expose _id as string to the world but use (convert) them to ObjectId when talking to mongo.

我有一个助手创建灯具:

I've an helper creating fixtures:

var _ = require('lodash'),
    Promise = require('bluebird'),
    MongoDb = require('mongodb');

var fixtureData = [
    {
        'uuid': '1',
        'owner': 'A',
        'data': 'someData1'
    },
    {
        'uuid': '2',
        'owner': 'A',
        'data': 'someData2'
    },
    {
        'uuid': '3',
        'owner': 'B',
        'data': 'someData3'
    },
    {
        'uuid': '4',
        'owner': 'A',
        'data': 'someData4'
    },
    {
        'uuid': '5',
        'owner': 'A',
        'data': 'someData5'
    },
    {
        'uuid': '6',
        'owner': 'B',
        'data': 'someData6'
    }
]

module.exports.loadFixtures  = function (url, collectionName) {
    var MongoClient = MongoDb.MongoClient;

    return MongoClient.connect(url, {
        promiseLibrary: Promise
    }).then(function (db) {
        return db.dropCollection(collectionName)
            .catch(function (err) {
                if (err.message === 'ns not found') {
                    return 'does not exist';
                }
                throw err;
            })
            .then(function () {
                return db.collection(collectionName).insertMany(fixtureData);
            }).then(function (result) {
                _.forEach(result.insertedIds, function (value, idx) {
                    fixtureData[idx]._id = value;
                });
                return db;
            });
    }).then(function (db) {
        db.close();
        return fixtureData;
    });
};

我使用jasmine进行测试,我在每个beforeEach上调用它来始终以相同的精确度开始每个测试情况。

I use jasmine to test and I call this at every beforeEach to always start each test with the same exact situation.

然后我有一个测试删除的功能(简单地说):

I then have a function to test the delete (simplyfing):

var dataToDelete = fixtureData[0];
sut.deleteDocument(dataToDelete_.id)
    .then(function(result) {
        expect(....);
    });

在我的deleteDocument中我没有做任何特别的事情:

Inside my deleteDocument I do nothing special:

db.collection('myCollection').deleteOne({ _id: theId })
    then(function(result)) {
        if (result.deletedCount === 0) {
            throw new Error('No document to delete with ID: ' + _id);
        }
        return null;
    });

这里的 theId 变量获得转换a mongo ObjectId id作为参数传递,函数非常简单:

The theId variable here is obtained converting in a mongo ObjectId the id passed as parameter with a very simple function:

function (id) {
    if (_.isString(id)) {
        return MongoDb.ObjectId(id);
    }
    if (MongoDb.ObjectId.isValid(id) === true) {
        return id;
    }
    throw new Error('Invalid ObjectId');
};

我正在使用mongodb Node.js驱动程序版本 2.2.16

I'm using mongodb Node.js driver version 2.2.16.

这里的问题是我总是会收到 deletedCount = 0 如果我使用的话 ObjectId as _id 但如果我将其转换为String,则可以正常工作并删除该功能。

The problem here is that I ALWAYS receive a deletedCount = 0 if I use an ObjectId as _id but if I covert it to String it works and delete the function.

这完全困扰我,因为我发现的每个文档和每个示例总是说 _id ObjectId

This completely puzzle me because every documentation I've found and every example always say _id is a ObjectId.

有人可以解释发生了什么吗?

Can someone explain what's going on?

(答案让我进去正确的方向,但这是你正在寻找的实际的答案,如果你最终在这种情况下)如果你最终在这种情况下你在 _id 字段中传递字符串时创建文档。找出你为什么这样做,如果它不是你想要修复它

(the answer got me in the right direction but this is the actual anwer you are looking for if you end up in this situation) if you end up in this situation you are passing strings in the _id field when creating the document. Find out why you do that if it is not intended and you'll fix it

推荐答案

你确定你的灯具不是在不同的测试之间损坏了吗?

Are you sure your fixtures aren't mangled between different tests?

顺便说一句不应该

return MongoDb.ObjectId(id);

return new MongoDb.ObjectId(id);

这篇关于通过_id的MongoDB Node.js deleteOne不能在ObjectId上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆