web-dev-qa-db-ja.com

Parse.comから1000行以上を取得するにはどうすればよいですか?

リストビューのデータを取得するためにParseを使用しています。残念ながら、リクエストはデフォルトで最大1000に制限されています。私のクラスには最大1000をはるかに超えています。 iOSでそれを行う方法を示すリンクをWebで見つけましたが、Androidでどのように行いますか? Webリンク

私は現在、すべての項目が完了するまで(100)、すべてのデータをループ内の配列リストに追加してから、それらをリストに追加しています

19
SquiresSquire

私は自分の目標を達成する方法を理解しました:

グローバル変数を宣言する

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
                }
        }
    };
}
43
SquiresSquire

これがJavaScriptバージョンの約束なしです。

これらはグローバル変数です(コレクションは必要ありません。私の悪い習慣です)。

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

これは、結果を取得する「ループ」関数です。

//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);
14
deLux_247

Java

したがって、5年4か月後、@ SquiresSquireの 上記の回答 は、私のために機能させるためにいくつかの変更が必要でした。それをあなたと共有したいと思います。

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

 ParseQuery<ParseObject> parseQuery = new ParseQuery<ParseObject>("CLASSNAME");
        parseQuery.setLimit(1000);
        parseQuery.findInBackground(getAllObjects());

FindCallback <ParseObject> getAllObjects() {
        return new FindCallback <ParseObject>() {
            @Override
            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("CLASSNAME");
                        query.setSkip(skip);
                        query.setLimit(limit);
                        query.findInBackground(getAllObjects());
                    }
                    //We have a full PokeDex
                    else {
                        //USE FULL DATA AS INTENDED
                    }
                }
            }

        };
2
SHADOW.NET

YAS(さらに別の解決策!)javascriptasync()await()を使用します。

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);
  }

}
1
Dygerati

A Swift例:

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の例から採用。

1
nyxee

C#で私はこの再帰を使用します:

_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);
    });
}
_

使用法:C#ではGetAll()、JSではgetAll([])

クラスRowのすべての行をlistに格納します。各リクエストで1000行を取得し、listの現在のサイズをスキップします。エクスポートされた行の現在の数が予想と異なる場合、再帰は停止します。

1
Termininja

CloudCodeを使用してこれを実現できます...コレクション全体を列挙し、そこから応答を構築する呼び出し可能なカスタム関数を作成しますが、より賢明な選択は、リクエストをページ分割し、レコードを1000(またはそれ以下)でフェッチすることです。必要に応じて動的にリストに追加します。

0
Pete Martin

Javascript /クラウドコード

これがすべてのクエリに対して機能するクリーンな方法です

async function fetchAllIgnoringLimit(query,result) {
  const limit = 1000;
  query.limit(limit);
  query.skip(result.length);

  const results = await query.find();
  result = result.concat(results)

  if(results.length === limit) {
    return await fetchAllIgnoringLimit(query,result );
  } else {
    return result;
  }

}

そして、これがそれを使用する方法です

var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
//instead of var result = await query.find();
var result = await fetchAllIgnoringLimit(query,new Array());
console.log("got "+result.length+" rows")
0
Omkar

重要openソース解析サーバーを使用している場合、ここでの回答はどれも役に立ちません。デフォルトですが、できますクエリに任意の値を入力します、limit(100000)// WORKS再帰の必要はありません呼び出しは、必要な行数に制限を設定するだけです

https://github.com/parse-community/parse-server/issues/538

0
Omkar