Как получить более 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
. Рекурсия останавливается, когда текущее количество экспортируемых строк отличается от ожидаемого.