Tous les produits
Search
Centre de documentation

Tablestore:Sorting and Paging

Dernière mise à jour :Aug 08, 2026

Lorsque vous interrogez des données à l'aide d'un index de recherche, vous pouvez contrôler l'ordre des résultats en définissant une méthode de tri au préalable ou en la spécifiant au moment de la requête. Si l'ensemble de résultats est volumineux, utilisez la pagination pour accéder rapidement aux données souhaitées.

IndexSort

Par défaut, un index de recherche trie les données selon la valeur IndexSort configurée. Lorsque vous interrogez des données via cet index, IndexSort détermine l'ordre par défaut des résultats.

Vous pouvez définir une valeur IndexSort personnalisée lors de la création d'un index de recherche. Si vous ne spécifiez pas de valeur personnalisée pour IndexSort, le tri s'effectue par défaut selon la clé primaire.

Important
  • IndexSort prend uniquement en charge PrimaryKeySort (tri par clé primaire) et FieldSort (tri par valeur de champ).

  • Les index de recherche contenant des champs de type nested ne prennent pas en charge IndexSort.

  • Après la création d'un index de recherche, vous pouvez utiliser la fonctionnalité de modification dynamique du schéma pour modifier le paramètre IndexSort.

Tri au moment de la requête

Le tri n'est pris en charge que pour les champs dont le paramètre EnableSortAndAgg est défini sur true.

Vous pouvez spécifier une méthode de tri pour chaque requête. Un index de recherche prend en charge quatre types de trieurs. Vous pouvez également combiner plusieurs trieurs afin d'ordonner les résultats selon une séquence de critères.

ScoreSort

Trie les résultats selon leur score de pertinence, calculé à l'aide de l'algorithme BM25. Cette méthode convient aux scénarios nécessitant un classement par pertinence, tels que la recherche en texte intégral.

Important
  • Pour trier les résultats par score de pertinence, vous devez spécifier explicitement ScoreSort. À défaut, les résultats sont triés selon le paramètre IndexSort de l'index.

  • Lorsque vous utilisez ScoreSort, les champs FuzzyKeyword ne sont pas inclus dans le processus de tri et le paramètre weight n'a aucun effet sur ces champs.

searchQuery := search.NewSearchQuery()
searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.ScoreSort{
            Order: search.SortOrder_DESC.Enum(), // Sort in descending order of score.
        },
    },
})

PrimaryKeySort

Trie les résultats selon la clé primaire, ce qui permet d'ordonner les éléments par leurs identifiants uniques.

searchQuery := search.NewSearchQuery()
searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.PrimaryKeySort{
            Order: search.SortOrder_ASC.Enum(),
        },
    },
})

FieldSort

Trie les résultats selon la valeur d'un champ spécifique. Cette approche est utile dans les applications de commerce électronique ou les réseaux sociaux, où il peut être nécessaire de classer les articles selon des attributs tels que le volume des ventes ou le nombre de pages vues.

Tri sur une seule colonne

Trie les résultats en fonction des valeurs d'un seul champ.

// Sort the results based on the Col_Long field in descending order.
searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.FieldSort{
            FieldName: "Col_Long",
            Order:     search.SortOrder_DESC.Enum(),
        },
    },
})

Tri multicolumnes

Trie d'abord les résultats selon les valeurs d'un premier champ, puis selon celles d'un second.

searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.FieldSort{
            FieldName: "col1",
            Order:     search.SortOrder_ASC.Enum(),
        },
        &search.FieldSort{
            FieldName: "col2",
            Order:     search.SortOrder_DESC.Enum(),
        },
    },
})

Tri des valeurs manquantes

Lorsqu'un champ de tri est absent d'un document, le paramètre MissingValue détermine sa position dans les résultats triés.

Le comportement de tri est le suivant :

  • Si vous définissez MissingValue sur search.FirstWhenMissing, les documents ne contenant pas le champ sont placés au début, que l'ordre de tri soit croissant (asc) ou décroissant (desc).

  • Si vous définissez MissingValue sur search.LastWhenMissing ou nil, les documents ne contenant pas le champ sont placés à la fin, quel que soit l'ordre de tri.

    // Sort the results based on the view_at field in ascending order,
    // and place documents with missing values at the end.
    searchQuery.SetSort(&search.Sort{
        []search.Sorter{
            &search.FieldSort{
                FieldName:    "view_at",
                Order:        search.SortOrder_ASC.Enum(),
                MissingValue: search.LastWhenMissing,
            },
        },
    })

GeoDistanceSort

Trie les résultats selon la distance par rapport à un point géographique. Cette fonctionnalité est utile pour les applications de cartographie et de logistique, par exemple pour classer les restaurants à proximité en fonction de leur distance par rapport à votre position actuelle.

searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.GeoDistanceSort{
            FieldName: "location",   // Specify the name of the GeoPoint field.
            Points:    []string{"40,-70"}, // Specify the center point.
        },
    },
})

Méthodes de pagination

Pour paginer les résultats, vous pouvez utiliser soit les paramètres Limit et Offset, soit un jeton.

Pagination avec Limit et Offset

Vous pouvez utiliser Limit et Offset pour la pagination. La somme de Limit et Offset doit être inférieure ou égale à 100 000, et la valeur maximale de Limit est de 100.

Remarque

Pour augmenter la limite supérieure du paramètre Limit, consultez la rubrique Comment augmenter le paramètre limit à 1000 pour les requêtes d'index de recherche ?.

Si vous ne spécifiez pas ces paramètres, Limit prend par défaut la valeur 10 et Offset prend par défaut la valeur 0.

searchQuery := search.NewSearchQuery()
searchQuery.SetLimit(10)
searchQuery.SetOffset(10) 

Pagination avec un jeton

Pour la pagination profonde, utilisez un jeton, car cette méthode n'impose aucune limitation de profondeur.

Si une requête renvoie plus de résultats qu'une seule réponse ne peut en contenir, le serveur fournit un NextToken. Utilisez ce jeton dans une requête suivante pour récupérer la page suivante.

Par défaut, la pagination par jeton permet uniquement d'avancer. Toutefois, comme un jeton reste valide pendant toute la durée d'une session de requête, vous pouvez mettre en cache les jetons précédents pour implémenter une pagination arrière.

Important

Si vous devez persister le NextToken ou l'envoyer à une application frontale, utilisez l'encodage Base64 pour le convertir en chaîne de caractères afin de le stocker et le transmettre. Étant donné que le jeton est un slice d'octets et non une chaîne, une conversion directe via string(NextToken) entraîne une perte de données.

Lorsque vous utilisez un jeton, la méthode de tri de la requête précédente est automatiquement appliquée. Par conséquent, vous ne pouvez pas spécifier les paramètres Sort ou Offset dans une requête basée sur un jeton. Vous pouvez uniquement lire les données de manière séquentielle, page par page.

Important

Les index de recherche contenant des champs de type nested ne prennent pas en charge IndexSort. Par conséquent, vous devez spécifier une méthode de tri dans votre requête pour activer la pagination. Sans ordre de tri spécifié, le serveur ne renverra pas de NextToken, même si d'autres résultats existent.

/**
 * Read data page by page by using a token.
 * If a SearchResponse contains a NextToken, you can use it to initiate the next query.
 * A nil NextToken indicates that all matching data has been retrieved.
 */
func QueryRowsWithToken(client *tablestore.TableStoreClient, tableName string, indexName string) {
    querys := []search.Query{
        &search.MatchAllQuery{},
        &search.TermQuery{
            FieldName: "Col_Keyword",
            Term:      "tablestore",
        },
    }
    for _, query := range querys {
        fmt.Printf("Test query: %#v\n", query)
        searchRequest := &tablestore.SearchRequest{}
        searchRequest.SetTableName(tableName)
        searchRequest.SetIndexName(indexName)
        searchQuery := search.NewSearchQuery()
        searchQuery.SetQuery(query)
        searchQuery.SetLimit(10)
        searchQuery.SetGetTotalCount(true)
        searchRequest.SetSearchQuery(searchQuery)
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        rows := searchResponse.Rows
        requestCount := 1
        for searchResponse.NextToken != nil {           
            {  
	              // To persist or send the NextToken, Base64-encode it.
	              // The token is a byte slice, not a string; direct conversion causes data loss.
	              tokenAsString := base64.StdEncoding.EncodeToString(searchResponse.NextToken)
	              // Decode the string back into a byte slice.
	              tokenAsByte, err := base64.StdEncoding.DecodeString(tokenAsString)
	              if err != nil {
		                fmt.Printf("len:%d, %#v",len(tokenAsByte), err)
		                return
	              }
            }
            searchQuery.SetToken(searchResponse.NextToken)
            searchResponse, err = client.Search(searchRequest)
            if err != nil {
                fmt.Printf("%#v", err)
                return
            }
            requestCount++
            for _, r := range searchResponse.Rows {
                rows = append(rows, r)
            }
        }
        fmt.Println("IsAllSuccess: ", searchResponse.IsAllSuccess)
        fmt.Println("TotalCount: ", searchResponse.TotalCount)
        fmt.Println("RowsSize: ", len(rows))
        fmt.Println("RequestCount: ", requestCount)
    }
}