一劳永逸地防止 Parse Server 中重复的最终方法

问题描述 投票:0回答:4

我们现在面临的解析服务器最大的问题之一是重复。尽管我们已经实现了 Parse 云代码来通过

beforeSave
afterSave
方法来防止此类事件,同时添加了外部中间件以在保存之前检查现有对象,但我们仍然面临着一遍又一遍的重复,特别是在并发操作上。

这是我们防止特定类重复的代码:

Parse.Cloud.beforeSave("Category", function(request, response) {
    var newCategory = request.object;
    var name = newCategory.get("name");
    var query = new Parse.Query("Category");
    query.equalTo("name", name);
    query.first({
        success: function(results) {
            if(results) {
                if (!request.object.isNew()) { // allow updates
                    response.success();
                } else {
                    response.error({errorCode:400,errorMsg:"Category already exist"});
                }
            } else {
                response.success();
            }
        },
        error: function(error) {
            response.success();
        }
    });
});
Parse.Cloud.afterSave("Category", function(request) {
    var query = new Parse.Query("Category");
    query.equalTo("name", request.object.get("name"));
    query.ascending("createdAt");
    query.find({
        success:function(results) {
            if (results && results.length > 1) {
                for(var i = (results.length - 1); i > 0 ; i--) {
                    results[i].destroy();
                }
            }
            else {
                // No duplicates
            }
        },
        error:function(error) {
        }
    });
});

上面的代码能够防止一些重复,但大多数仍然会执行,例如:

防止与 Parse 服务器重复的“最终方法”是什么?

node.js parse-platform parse-server
4个回答
7
投票

您始终可以在 mongodb 中为文档中应该唯一的字段创建唯一索引。

这样任何与该索引冲突的保存都将被中止


0
投票

也许你应该写一些带有 Promise 的内容,例如:

Parse.Cloud.beforeSave("Category", function (request, response) {


    return new Promise((resolve, reject) => {

        var query = new Parse.Query("Category");
        query.equalTo("name", "Dummy");

        return query.first().then(function (results) {

            resolve(); // or reject()
        });
    })

});


Parse.Cloud.beforeSave("Category", async (request) => {

    (...)
    await results = query.first();

    // then your logic here
    response.success();
    response.error({ errorCode: 400, errorMsg: "Category already exist" })

})

0
投票

这是我的解决方案:

Parse.Cloud.beforeSave( 'ClassName', async ( request ) => {
    const columnName = 'columnName'
    const className = 'ClassName'

    if( request.object.isNew() ) {
        var newCategory = request.object
        var name = newCategory.get( columnName )
        var query = new Parse.Query( className )
        query.equalTo( columnName, name )
    
        const results = await query.count()

        if( results === 0 ) {
            // no response.success needed 
            // https://github.com/parse-community/parse-server/blob/alpha/3.0.0.md
        } else {
            throw 'Is not unique'; 
        }
    }
} )

0
投票

不确定是否还需要,但我最近遇到了同样的问题。正如这里已经回答的那样(但没有解释)

query.first()
调用是异步的,您需要
await
响应。正确的代码可能如下所示:

Parse.Cloud.beforeSave('Category', async (request) => {
   const newEntry = request.object;
   const teamId = newEntry.get('name');
   const query = new Parse.Query('Category');
   query.equalTo('name', name);

   //check database for entries
   const results = await query.count();

   if (results === 0) {
      //no existing entries
   } else {
      //there are already existing entries
      throw('Category already exist');
   }
});

尽管需要说明,使用

query.first()
函数可能会提高性能,因为它会在第一次输入后停止。但是,我发现这种方法更容易理解,并且如果您的数据库不是很大的话,应该不会更快。

此外,

afterSave
功能是多余的,可以删除。

© www.soinside.com 2019 - 2024. All rights reserved.