> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Solana DAS API-Paginierung: Effiziente Abfrage von großen Datensätzen

> Seitenbasierte und Keyset-Paginierung für die Solana DAS API. Durchsuchen Sie große Datensätze effizient mit Cursor- und bereichsbasierten Strategien und parallelen Abfragen.

## Übersicht

DAS API-Methoden geben bis zu 1.000 Datensätze pro Aufruf zurück. Um mehr abzurufen, paginieren Sie – machen Sie mehrere Aufrufe und durchlaufen Sie Seiten von Daten. Helius unterstützt zwei Mechanismen: seitenbasierte und Keyset-Paginierung.

Seitenbasierte Paginierung ist der einfachste Einstieg. Die Keyset-Paginierung ist für fortgeschrittene Benutzer gedacht, die große (500k+) Datensätze effizient abfragen möchten.

## Wann man es verwendet

* **Seitenbasiert** — statische Ansichten, Dashboards und die meisten alltäglichen Abfragen. Einfach und intuitiv.
* **Keyset (Cursor oder Bereich)** — große Datensätze (gesamte Sammlungen, 500k+ Assets), bei denen das seitenbasierte Durchlaufen langsam wird.
* **Paralleles Keyset** — die schnellste Option, um eine gesamte Sammlung zu scannen, indem der Adressbereich partitioniert wird.

## Sortieroptionen

Sie können Ergebnisse nach verschiedenen Feldern sortieren, indem Sie das `sortBy`-Feld verwenden:

| Wert            | Sortiert nach                               | Empfohlen? |
| --------------- | ------------------------------------------- | ---------- |
| `id`            | Asset-ID in binär (Standard)                | Ja         |
| `created`       | Datum der Erstellung des Assets             | Ja         |
| `recent_action` | Datum der letzten Aktualisierung des Assets | Nein       |
| `none`          | Keine Sortierung                            | Nein       |

Das Deaktivieren der Sortierung liefert die schnellsten Ergebnisse, aber da die Daten ungeordnet sind, können Sie inkonsistente Ergebnisse beim Paginieren erhalten.

## Seitenbasierte Paginierung

Sie geben die Seitennummer und die Anzahl der Elemente pro Seite an. Um zur nächsten Seite zu gelangen, erhöhen Sie die Seitennummer. Dies ist einfach, intuitiv und schnell für die meisten Anwendungsfälle.

<Accordion title="Beispiel">
  ```javascript theme={"system"}
  const url = `https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY`

  const example = async () => {
      let page = 1;
      let items = [];
      while (true) {
          const response = await fetch(url, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                  jsonrpc: '2.0',
                  id: 'my-id',
                  method: 'searchAssets',
                  params: {
                      grouping: ['collection', '5PA96eCFHJSFPY9SWFeRJUHrpoNF5XZL6RrE1JADXhxf'],
                      page: page,
                      limit: 1000,
                      sortBy: { sortBy: 'id', sortDirection: 'asc' },
                  },
              }),
          });
          const { result } = await response.json();
          if (result.items.length == 0) {
              console.log('No items remaining');
              break;
          } else {
              console.log(`Processing results from page ${page}`);
              items.push(...result.items);
              page += 1;
          }
      }
      console.log(`Got ${items.length} total items`);
  };
  example();
  ```
</Accordion>

Die Verwendung von Seiten erfordert, dass die Datenbank alle Elemente durchläuft, bis sie zur nächsten Seite gelangt. Wenn Sie z. B. Seite 100 mit einer Seitengröße von 1.000 anfordern, muss die Datenbank die ersten 1M Datensätze durchlaufen, bevor Ihre Daten zurückgegeben werden. Aus diesem Grund wird die seitenbasierte Paginierung für große Datensätze nicht empfohlen — die Keyset-Paginierung eignet sich viel besser für diese Arbeitslasten.

## Keyset-Paginierung

Sie definieren Seiten, indem Sie Bedingungen festlegen, die den Datensatz filtern. Zum Beispiel: "Geben Sie mir alle Assets mit einer ID > X, aber einer ID \< Y." Sie durchlaufen den gesamten Datensatz, indem Sie X oder Y bei jedem Aufruf ändern. Es gibt zwei Methoden der Keyset-Paginierung:

1. **Cursor-basiert** — einfacher zu verwenden, aber weniger flexibel.
2. **Bereichsbasiert** — komplexer, aber sehr flexibel.

Keyset-Paginierung wird nur unterstützt, wenn nach `id` sortiert wird.

### Cursor-basiert

Eine DAS-Abfrage ohne Paginierungsparameter gibt einen Cursor zurück. Übergeben Sie den Cursor zurück an die DAS API, um von dort fortzufahren, wo Sie aufgehört haben.

<Accordion title="Beispiel">
  ```typescript theme={"system"}
  const url = `https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY`

  const example = async () => {
      let items = [];
      let cursor;
      while (true) {
          let params = {
              grouping: ['collection', '5PA96eCFHJSFPY9SWFeRJUHrpoNF5XZL6RrE1JADXhxf'],
              limit: 1000,
              sortBy: { sortBy: 'id', sortDirection: 'asc' },
          } as any;
          if (cursor != undefined) {
              params.cursor = cursor;
          }
          const response = await fetch(url, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                  jsonrpc: '2.0',
                  id: 'my-id',
                  method: 'searchAssets',
                  params: params,
              }),
          });
          const { result } = await response.json();
          if (result.items.length == 0) {
              console.log('No items remaining');
              break;
          } else {
              console.log(`Processing results for cursor ${cursor}`);
              cursor = result.cursor;
              items.push(...result.items);
          }
      }
      console.log(`Got ${items.length} total items`);
  };
  example();
  ```
</Accordion>

Zum Zeitpunkt des Schreibens ist der Cursor die letzte Asset-ID der Antwort; jedoch ist das Cursor-Design flexibel und kann jede Zeichenfolge unterstützen.

### Bereichsbasiert

Um über einen Bereich abzufragen, geben Sie `before` und/oder `after` an. Die Abfrage lautet im Wesentlichen "Geben Sie mir alle Assets nach X, aber vor Y." Sie durchlaufen den Datensatz, indem Sie den Parameter `before` oder `after` bei jedem Aufruf aktualisieren.

<Accordion title="Beispiel">
  ```javascript theme={"system"}
  const url = `https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY`

  const example = async () => {
      // Two NFTs from the Tensorian collection.
      // The "start" item has a lower asset ID (in binary) than the "end" item.
      // We will traverse in ascending order.
      let start = '6CeKtAYX5USSvPCQicwFsvN4jQSHNxQuFrX2bimWrNey';
      let end = 'CzTP4fUbdfgKzwE6T94hsYV7NWf1SzuCCsmJ6RP1xsDw';
      let sortDirection = 'asc';
      let after = start;
      let before = end;
      let items = [];

      while (true) {
          const response = await fetch(url, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                  jsonrpc: '2.0',
                  id: 'my-id',
                  method: 'searchAssets',
                  params: {
                      grouping: ['collection', '5PA96eCFHJSFPY9SWFeRJUHrpoNF5XZL6RrE1JADXhxf'],
                      limit: 1000,
                      after: after,
                      before: before,
                      sortBy: { sortBy: 'id', sortDirection: sortDirection },
                  },
              }),
          });
          const { result } = await response.json();
          if (result.items.length == 0) {
              console.log('No items remaining');
              break;
          } else {
              console.log(`Processing results with (after: ${after}, before: ${before})`);
              after = result.items[result.items.length - 1].id;
              items.push(...result.items);
          }
      }
      console.log(`Got ${items.length} total items`);
  };
  example();
  ```
</Accordion>

## Parallele Abfrage mit Keysets (fortgeschritten)

Fortgeschrittene Benutzer, die große Datensätze abfragen (zum Beispiel gesamte komprimierte NFT-Sammlungen), sollten die Keyset-basierte Paginierung aus Leistungsgründen verwenden. Das folgende Beispiel zeigt, wie man parallel abfragen kann, indem der Solana-Adressbereich partitioniert und die Parameter `before`/`after` verwendet werden. Diese Methode ist schnell, effizient und sicher.

<Accordion title="Beispiel">
  Im unten stehenden Beispiel scannen wir die gesamte Tensorian-Sammlung (\~10k Datensätze). Sie partitioniert den Solana-Adressraum in 8 Bereiche und scannt diese Bereiche gleichzeitig. Dies ist weitaus schneller als die anderen Ansätze.

  ```typescript theme={"system"}
  import base58 from 'bs58';

  const url = `https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY`

  const main = async () => {
      let numParitions = 8;
      let partitons = partitionAddressRange(numParitions);
      let promises = [];
      for (const [i, partition] of partitons.entries()) {
          let [s, e] = partition;
          let start = bs58.encode(s);
          let end = bs58.encode(e);
          console.log(`Parition: ${i}, Start: ${start}, End: ${end}`);

          let promise: Promise<number> = new Promise(async (resolve, reject) => {
              let current = start;
              let totalForPartition = 0;
              while (true) {
                  const response = await fetch(url, {
                      method: 'POST',
                      headers: {
                          'Content-Type': 'application/json',
                      },
                      body: JSON.stringify({
                          jsonrpc: '2.0',
                          id: 'my-id',
                          method: 'searchAssets',
                          params: {
                              grouping: ['collection', '5PA96eCFHJSFPY9SWFeRJUHrpoNF5XZL6RrE1JADXhxf'],
                              limit: 1000,
                              after: current,
                              before: end,
                              sortBy: { sortBy: 'id', sortDirection: 'asc' },
                          },
                      }),
                  });
                  const { result } = await response.json();
                  totalForPartition += result.items.length;
                  console.log(`Found ${totalForPartition} total items in parition ${i}`);
                  if (result.items.length == 0) {
                      break;
                  } else {
                      current = result.items[result.items.length - 1].id;
                  }
              }
              resolve(totalForPartition);
          });
          promises.push(promise);
      }
      let results = await Promise.all(promises);
      let total = results.reduce((a, b) => a + b, 0);
      console.log(`Got ${total} total items`);
  };

  // Function to convert a BigInt to a byte array
  function bigIntToByteArray(bigInt: bigint): Uint8Array {
      const bytes = [];
      let remainder = bigInt;
      while (remainder > 0n) {
          // use 0n for bigint literal
          bytes.unshift(Number(remainder & 0xffn));
          remainder >>= 8n;
      }
      while (bytes.length < 32) bytes.unshift(0); // pad with zeros to get 32 bytes
      return new Uint8Array(bytes);
  }

  function partitionAddressRange(numPartitions: number) {
      let N = BigInt(numPartitions);

      // Largest and smallest Solana addresses in integer form.
      // Solana addresses are 32 byte arrays.
      const start = 0n;
      const end = 2n ** 256n - 1n;

      // Calculate the number of partitions and partition size
      const range = end - start;
      const partitionSize = range / N;

      // Calculate partition ranges
      const partitions: Uint8Array[][] = [];
      for (let i = 0n; i < N; i++) {
          const s = start + i * partitionSize;
          const e = i === N - 1n ? end : s + partitionSize;
          partitions.push([bigIntToByteArray(s), bigIntToByteArray(e)]);
      }

      return partitions;
  }

  main();
  ```
</Accordion>

## Nächste Schritte

<CardGroup cols={3}>
  <Card title="Assets suchen" icon="magnifying-glass" href="/docs/de/das/search">
    Filtern Sie Assets nach Besitzer, Sammlung und Token-Typ.
  </Card>

  <Card title="Assets abrufen (NFTs)" icon="image" href="/docs/de/das/get-nfts">
    Rufen Sie NFTs, Sammlungen, Editionen und Nachweise ab.
  </Card>

  <Card title="DAS API-Referenz" icon="code" href="/docs/de/api-reference/das">
    Vollständige Schemata für jede DAS-Methode.
  </Card>
</CardGroup>
