首页 > 解决方案 > MongoJS 不按 ID 删除

问题描述

 async deleteRecipeById(recipeId){
    try{
        const client = new MongoClient(this.uriString);
        
        await client.connect();
        const db = client.db(this.databaseString);
        const recipeCollection = db.collection(this.collectionString);

        //console.log(await recipeCollection.find({recipeName:recipeName}).toArray());
        var recipeIdAsObject = new ObjectId(recipeId);
        var result = recipeCollection.deleteMany({"_id":recipeIdAsObject});
        client.close();
        return result;
    }
    catch(e){
        console.error(e);
    }
}

我正在测试我的 mongo 驱动程序,但我终其一生都无法弄清楚为什么这不起作用。我用我的 deleteRecipeByName() 运行相同的测试并且测试通过了。所以这对我来说表明我的测试夹具很好。这意味着我知道该配方存在于具有正确 ID 的数据库中。

在我运行测试之前,我什至调用了一个我已经测试过的 getRecipeByName 函数,以确保配方存在于我正在寻找的 ID 中,这就是结果。

[
{
  _id: 0,
  recipeName: 'mock0',
  recipeIngredients: [ 'i0', 'i1', 'i2' ]
}
]

还有我的测试功能

describe('Testing delete Recipe',()=>{
it('1. Delete known recipe',(done)=>{
    var uri = "mongodb://localhost:27017";
    var dbname = "testRecipes";
    var collectionName = "testCollectionMessy";
    let driver = new MongoDriver(uri,dbname,collectionName);
    driver.dropCollection().then(()=>{//Clean collection for testing... NEVER CALL ON PRODUCTION COLLECTION
        driver.addMockData().then((p)=>{
            driver.getRecipeById(mockData[0]._id).then((p)=>{
                console.log(p);
            })
            driver.deleteRecipeById(0).then((p)=>{
                console.log(p);
                console.log(mockData[0]._id);
                assert.deepEqual(p.deletedCount,1);
                done();
            }).catch((e)=>{
                console.log(e);
                done(e);
            })
        });
    }); 
})
})

这是我从 JSON 导入的 mockData

[
 {"_id":0,"recipeName":"mock0","recipeIngredients":["i0","i1","i2"]},
 {"_id":1,"recipeName":"mock1","recipeIngredients":["i0","i1","i2"]},
 {"_id":2,"recipeName":"mock2","recipeIngredients":["ingredient"]}
]

标签: javascriptnode.jsmongodbmongojs

解决方案


问题是如何管理receipeId。

new ObjectId(id)如果 id 不是有效的 mongo 对象 id,则抛出,因此您可以添加一个片段来管理这两种格式,如下所示:

 async deleteRecipeById(recipeId){
    try{
        const client = new MongoClient(this.uriString);
        
        await client.connect();
        const db = client.db(this.databaseString);
        const recipeCollection = db.collection(this.collectionString);

        var recipeIdAsObject;
        if(/^(?=[a-f\d]{24}$)(\d+[a-f]|[a-f]+\d)/i.test(recipeId)){
           recipeIdAsObject = new ObjectId(recipeId);
        } else {
           recipeIdAsObject = recipeId
        }

        var result = recipeCollection.deleteMany({"_id":recipeId});
        client.close();
        return result;
    }
    catch(e){
        console.error(e);
        // it is dangerous to ignore errors
    }
}

我建议只选择一种格式,否则可能很难跨应用程序进行查询。


推荐阅读