简体   繁体   English

通过_id的MongoDB Node.js deleteOne在ObjectId上不起作用

[英]MongoDB Node.js deleteOne via _id doesn't work on ObjectId

I'm trying to write test (spec) on a mongo DB wrapper and stumbled on this weird issue. 我正在尝试在mongo DB包装器上编写测试(规范),但偶然发现了这个奇怪的问题。

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. 我的代码建立在mongodb的薄包装之上,将_id作为字符串暴露给世界,但在与mongo对话时将其使用(转换)为ObjectId。

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;
    });
};

I use jasmine to test and I call this at every beforeEach to always start each test with the same exact situation. 我使用茉莉花进行测试,并在每次beforeEach时都调用它,以始终在相同的确切情况下开始每次测试。

I then have a function to test the delete (simplyfing): 然后,我有一个功能来测试删除(简单化):

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

Inside my deleteDocument I do nothing special: 在我的deleteDocument里面,我没有做任何特别的事情:

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;
    });

The theId variable here is obtained converting in a mongo ObjectId the id passed as parameter with a very simple function: 这里的theId变量是通过一个非常简单的函数在mongo ObjectId转换作为参数传递的id来获得的:

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

I'm using mongodb Node.js driver version 2.2.16 . 我正在使用mongodb Node.js驱动程序2.2.16版本。

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. 这里的问题是,如果我将ObjectId用作_id ,我总是会收到deletedCount = 0 ,但是如果我将其deletedCount = 0为String,它将起作用并删除该函数。

This completely puzzle me because every documentation I've found and every example always say _id is a ObjectId . 这完全使我感到困惑,因为我找到的每个文档和每个示例总是说_id是一个ObjectId

Can someone explain what's going on? 有人可以解释发生了什么吗?

EDIT: (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. 编辑:(答案使我朝正确的方向前进,但是如果您遇到这种情况,这是您正在寻找的实际答案)如果您遇到这种情况,那么您在创建文档时会在_id字段中传递字符串。 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? 您确定不同测试之间的夹具没有受到干扰吗?

And by the way shouldn't 顺便说一句

return MongoDb.ObjectId(id);

be

return new MongoDb.ObjectId(id);

?

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

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