如何将数千个对象保存到Parse.com? [英] How do I save thousands of objects to Parse.com?

查看:76
本文介绍了如何将数千个对象保存到Parse.com?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的使用Parse的iOS应用中,某些用户将需要在一次操作中保存数千个对象.我尝试遍历数据数组并逐个创建/保存对象,但这导致对象保存到数据浏览器的速度非常慢.每个对象只需要包含几个字符串,所以我不明白为什么保存这些对象要花这么长时间.

In my iOS app that uses Parse, some users will need to save thousand of objects in one action. I've tried iterating through the array of data and creating/saving the objects one by one, but this results in the objects saving to my data browser pretty slowly. Each object only needs to contain a few strings, so I don't understand why its taking so long to save these objects.

是否存在将数千个对象保存到Parse的更快方法?

Is there a faster way to save thousands of objects to Parse?

推荐答案

我一直使用[PFObject saveAllInBackground:array block:^(BOOL成功,NSError * error){}];但是...我刚刚尝试成功的另一种方法是上载Json字符串作为PFFile(没有128k限制),然后使用云代码来解析它并创建必要的PFObjects.我能够使它少量使用,但是不幸的是,大量使用时云代码超时.相反,我选择利用后台作业来执行解析.在数据完全可用之前,这需要花费大量时间,但可以处理大量数据.上传时间本身要快得多.当使用1000个对象和3个字符串时,每个上载大约为0.8秒,而23秒将所有内容保存在后台,而5000个对象3个字符串中的每个仅上载2.5秒.除了更快的时间,您还可以获得进度更新.根据使用情况,与立即使数据可用相比,如果立即和快速上传很重要,则使用此替代方法可能效果最好.

I've always used [PFObject saveAllInBackground:array block:^(BOOL succeeded, NSError *error) {}]; but....another method I have just attempted semi-successfully, was to upload a Json string as a PFFile(no 128k limit), and then use cloud code to parse it and create the necessary PFObjects. I was able to get this to work with small quantities, but unfortunately the cloud code timed out when using a large quantity. I instead opted to utilize a background job to perform the parsing. This takes a considerable amount of time before the data is completely available, but can handle the large amount of data. The upload time itself was much quicker. When using 1000 objects with 3 strings each upload was roughly .8 seconds, vs 23 seconds doing a save all in background, 5000 objects 3 strings each was only 2.5 seconds upload time. In addition to the quicker time you also get progress updates. Depending on the use-case, utilizing this alternative may work best if immediate and quick upload is important, vs making the data immediately available.

IOS代码:

  NSMutableArray *array = [NSMutableArray array];
    for (int i = 0; i<5; i++) {
        //subclass of PFObject
        Employee *employee = [Employee object];
        employee.firstName = @"FName";
        employee.lastName = @"LName";
        employee.employeeID = @"fid54";
        [array addObject:[employee dictionaryWithValuesForKeys:employee.allKeys]];
    }
    //Seperate class only to store the PFFiles
    PFObject *testObject = [PFObject objectWithClassName:@"fileTestSave"];
    testObject[@"testFile"] = [PFFile fileWithData:[NSJSONSerialization dataWithJSONObject:array options:0 error:nil]];

    NSLog(@"started");
    //**notice I am only saving the test object with the NSData from the JSONString**
    [testObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (!error && succeeded) NSLog(@"succeeded");
        else NSLog(@"error");
    }];

已可以随时运行以下后台作业,而不是保存在beforeSave或afterSave云代码中(这可能会导致超时问题).它获取"fileTestSave"表中的所有行,解析这些行中的JSON字符串,并将其添加到"Person"表中.完成后,它将从表中开始行.都是异步的!

Edited: Instead of saving in the beforeSave or afterSave Cloud Code which can cause timeout issues, the background job below can be run anytime. It grab all rows in the "fileTestSave" table, parses the JSON strings in those rows, and adds them to the "Person" table. Once completed it will rows from the table. All asynchronously!

var _ = require('underscore.js');
Parse.Cloud.job("userMigration", function(request, status) 
{

    // Set up to modify user data
    Parse.Cloud.useMasterKey();
    //Table called fileTestSave stores a PFFile called "testFile" which we will use an HTTPRequest to get the data. Is there a better way to get the data?
    //This PFFile stores a json string which contains relavent data to add to the "Person" table
    var testFileSave = Parse.Object.extend("fileTestSave");
    var query = new Parse.Query(testFileSave);
    query.find().then(function(results) 
    {
        //Generate an array of promises
        var promises = [];

        _.each(results, function(testFileSaveInstance){
            //add promise to array
            promises.push(saveJsonPerson(testFileSaveInstance));
        });
        //only continue when all promises are complete
        return Parse.Promise.when(promises);
    }).then(function() 
    {

    // Set the job's success status
        console.log("Migration Completed NOW");
        status.success("Migration completed");
    }, function(error) {
    // Set the job's error status
        status.error("Uh oh, something went wrong.");
    });
});

function saveJsonPerson(fileTestSave)
{
    //Get the pffile testfile
    var testFile = fileTestSave.get("testFile");
    //get the fileURL from the PFFile to generate the http request
    var fileURL = testFile["url"]();
    //return the promise from the httpRequest
    return Parse.Cloud.httpRequest({
        method:"GET",
        url: fileURL
    }).then(function(httpResponse){
            //return the promise from the parsing
            return parsehttpResponse(httpResponse,fileTestSave);
        },
        function(error){
            console.log("http response error");
        }
    );
}

function parsehttpResponse(httpResponse,fileTestSave)
{   
    var jsonArray = eval( '(' + httpResponse.text + ')' );
    var saveArray =[];

    //parse each person in the json string, and add them to the saveArray for bulk saving later.
    for (i in jsonArray) 
    {
        var personExtend = Parse.Object.extend("Person");
        var person = new personExtend();
        person.set("classDiscriminator",jsonArray[i]["classDiscriminator"]);
        person.set("lastName",jsonArray[i]["lastName"]);
        person.set("firstName",jsonArray[i]["firstName"]);
        person.set("employeeID",jsonArray[i]["employeeID"]);
        saveArray.push(person);
    };
    //return the promise from the saveAll(bulk save)
    return Parse.Object.saveAll(
            saveArray
        ).then(function(){
                //return the promise from the destory
                return fileTestSave.destroy(

                    ).then(function(){

                    },function(error){
                            console.log("error destroying");
                        }
                );
        },function(error){
                console.log("Error Saving");
            }
    );
}

超时作为参考的旧云代码:

Old Cloud Code that timed out as reference:

Parse.Cloud.afterSave("fileTestSave", function(request) {

    //When accessing PFFiles you don't get the actual data, there may be an easier way, but I just utitlized an HTTPRequest to get the data, and then continued parsing.
    var file = request.object.get("testFile");
    var fileURL = file["url"]();
    console.log("URL:"+fileURL);
    Parse.Cloud.httpRequest({
            method:"GET",
            url: fileURL,
            success: function(httpResponse) 
            {
                var jsonArray = eval( '(' + httpResponse.text + ')' );
                var saveArray =[];
                for (i in jsonArray) 
                {
                    var personExtend = Parse.Object.extend("Person");
                    var person = new personExtend();
                                    //May be a better way to parse JSON by using each key automatically, but I'm still new to JS, and Parse so I set each individually.
                    person.set("classDiscriminator",array[i]["classDiscriminator"]);
                    person.set("lastName",array[i]["lastName"]);
                    person.set("firstName",array[i]["firstName"]);
                    person.set("employeeID",array[i]["employeeID"]);
                    saveArray.push(person);
                };
                Parse.Object.saveAll(saveArray,
                {
                    success: function(list) {
                      // All the objects were saved.
                    },
                    error: function(error) {
                      // An error occurred while saving one of the objects.
                    },
                });
            },
            error: function(httpResponse) {
            console.log("http response error");
            }
    });
});

这篇关于如何将数千个对象保存到Parse.com?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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