Как получить более 1000 строк с Parse.com?

Я использую Parse для извлечения данных для просмотра списка. К сожалению, они ограничивают запросы до 100 по умолчанию до 1000 макс. В моем классе у меня намного больше 1000 макс. Я нашел ссылку в Интернете, которая показывает способ сделать это на iOS, но как бы вы сделали это на Android? Веб-ссылка

В настоящее время я добавляю все данные в arraylist в цикле, пока все элементы не будут заполнены (100), а затем добавят их в список

Ответы

Ответ 1

Я выяснил, как достичь своей цели:

Объявить глобальную переменную

private static List<ParseObject>allObjects = new ArrayList<ParseObject>();

Создать запрос

final ParseQuery parseQuery = new ParseQuery("Objects");
parseQuery.setLimit(1000);
parseQuery.findInBackground(getAllObjects());

Обратный вызов для запроса

int skip=0;
FindCallback getAllObjects(){
    return new FindCallback(){
        public void done(List<ParseObject> objects, ParseException e) {
            if (e == null) {

                allObjects.addAll(objects);
                 int limit =1000;
                if (objects.size() == limit){
                    skip = skip + limit;
                    ParseQuery query = new ParseQuery("Objects");
                    query.setSkip(skip);
                    query.setLimit(limit);
                    query.findInBackground(getAllObjects());
                }
                //We have a full PokeDex
                else {
                    //USE FULL DATA AS INTENDED
                }
        }
    };
}

Ответ 2

Вот версия JavaScript без promises..

Это глобальные переменные (коллекции не требуются, просто моя дурная привычка).

   ///create a collection of cool things and instantiate it (globally)
    var CoolCollection = Parse.Collection.extend({
       model: CoolThing
    }), coolCollection = new CoolCollection();

Это функция "looping", которая получает ваши результаты.

//recursive call, initial loopCount is 0 (we haven't looped yet)
function getAllRecords(loopCount){

    ///set your record limit
    var limit = 1000;

    ///create your eggstra-special query
     new Parse.Query(CoolThings)
            .limit(limit)
            .skip(limit * loopCount) //<-important
            .find({
             success: function (results) {
                 if(results.length > 0){

                     //we do stuff in here like "add items to a collection of cool things"
                     for(var j=0; j < results.length; j++){
                         coolCollection.add(results[j]);
                     }

                     loopCount++; //<--increment our loop because we are not done

                     getAllRecords(loopCount); //<--recurse
                 }
                 else
                 {
                     //our query has run out of steam, this else{} will be called one time only
                     coolCollection.each(function(coolThing){
                        //do something awesome with each of your cool things
                     });
                 }
            },
             error: function (error) {
                //badness with the find
             }
         });
}

Вот как вы это называете (или вы могли бы сделать это по-другому):

getAllRecords(0);

Ответ 3

YAS (еще одно решение!) Используя async() и await() в javascript.

async parseFetchAll(collected = []) {
  let query = new Parse.Query(GameScore);
  const limit = 1000;

  query.limit(limit);
  query.skip(collected.length);

  const results = await query.find();

  if(results.length === limit) {
    return await parseFetchAll([ ...collected, ...results ]);
  } else {
    return collected.concat(results);
  }

}

Ответ 4

A Swift 3 Пример:

var users    = [String] ()
var payments = [String] ()
///set your record limit
let limit = 29
//recursive call, initial loopCount is 0 (we haven't looped yet)
func loadAllPaymentDetails(_ loopCount:  Int){
    ///create your NEW eggstra-special query
    let paymentsQuery  = Payments.query()
    paymentsQuery?.limit = limit
    paymentsQuery?.skip  = limit*loopCount
    paymentsQuery?.findObjectsInBackground(block: { (objects, error) in
        if let objects = objects {
            //print(#file.getClass(),"  ",#function,"  loopcount: ",loopCount,"      #ReturnedObjects: ",  objects.count)
            if objects.count > 0 {
                //print(#function, " no. of objects :", objects.count)
                for paymentsObject in objects {
                    let user   = paymentsObject[Utils.name] as! String
                    let amount = paymentsObject[Utils.amount] as! String
                    self.users.append(user)
                    self.payments.append(amount)
                }
                //recurse our loop with increment because we are not done
                self.loadAllPaymentDetails(loopCount + 1); //<--recurse
            }else {
                //our query has run out of steam, this else{} will be called one time only
                //if the Table had been initially empty, lets inform the user:
                if self.users.count == 1 {
                    Utils.createAlert(self, title: "No Payment has been made yet", message: "Please Encourage Users to make some Payments", buttonTitle: "Ok")
                }else {
                    self.tableView.reloadData()
                }
            }
        }else if error != nil {
            print(error!)
        }else {
            print("Unknown Error")
        }
    })
}

адаптирован из приведенного выше примера @deLux_247.

Ответ 5

Вы можете достичь этого с помощью CloudCode... Создайте настраиваемую функцию, которую вы можете вызвать, которая будет перечислять всю коллекцию и строить ответ от этого, но более разумным выбором будет разбиение на страницы ваших запросов и выборка записей 1000 (или даже меньше) за раз, добавляя их в свой список динамически по мере необходимости.

Ответ 6

В С# Я использую эту рекурсию:

private static async Task GetAll(int count = 0, int limit = 1000)
{
    if (count * limit != list.Count) return;
    var res = await ParseObject.GetQuery("Row").Limit(limit).Skip(list.Count).FindAsync();
    res.ToList().ForEach(x => list.Add(x));
    await GetAll(++count);
}

JS версия:

function getAll(list) {
    new Parse.Query(Row).limit(1000).skip(list.length).find().then(function (result) {
        list = list.concat(result);
        if (result.length != 1000) {
            //do here something with the list...
            return;
        }

        getAll(list);
    });
}

Использование: GetAll() в С# и getAll([]) в JS.

Я сохраняю все строки из класса Row в list. В каждом запросе я получаю 1000 строк и пропускаю текущий размер list. Рекурсия останавливается, когда текущее количество экспортируемых строк отличается от ожидаемого.