Elasticsearch 2.1: fenêtre de résultat trop grande (indice.fenêtre de résultat max)

nous extrayons des informations à partir D'Elasticsearch 2.1 et permet à l'utilisateur de page à travers les résultats. Lorsque l'utilisateur demande un numéro de page élevé, nous recevons le message d'erreur suivant:

fenêtre de résultat trop grande, à partir de + la taille doit être inférieure ou égale à: [10000] mais [10020]. Voir l'api scroll pour une plus grande efficacité façon de demander de grands ensembles de données. Cette limite peut être réglée en modifiant la [index.max_result_window] paramètre du niveau de l'indice

le docu élastique dit que c'est en raison de la consommation de mémoire élevée et d'utiliser l'api de défilement:

des valeurs plus élevées que celles qui peuvent consommer des morceaux significatifs de mémoire tas par recherche et per shard exécutant la recherche. Il est plus sûr de laisser ce valeur car il s'agit d'une utilisation de l'api de défilement pour tout défilement en profondeur https://www.elastic.co/guide/en/elasticsearch/reference/2.x/breaking_21_search_changes.html#_from_size_limits

la chose est que je ne veux pas récupérer de grands ensembles de données. Je veux seulement récupérer une tranche de l'ensemble de données qui est très haut dans le jeu de résultats.

Scrolling n'est pas prévu pour temps réel les demandes des utilisateurs https://www.elastic.co/guide/en/elasticsearch/reference/2.2/search-request-scroll.html

cela me laisse avec quelques questions:

1) est-ce que la consommation de mémoire serait vraiment plus faible (si oui, pourquoi) si j'utilise l'api de défilement pour faire défiler le résultat 10020 (et ignorer tout ce qui est en dessous de 10000) au lieu de faire une demande de recherche "normale" pour le résultat 10000-10020?

2) Il ne semble pas que le défilement L'API est une option pour moi, mais que j'ai pour augmenter l'indice de".max_result_window". Quelqu'un a une expérience avec cela?

3) existe-il d'autres options pour résoudre mon problème?

62
demandé sur Ronald 2016-02-04 19:30:24

6 réponses

si vous avez besoin de grande pagination profonde, je pense qu'une seule variante de la solution est d'augmenter la valeur max_result_window

curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "index" : { "max_result_window" : 500000 } }'

l'augmentation de l'utilisation de la mémoire, I n'est pas trouvé pour des valeurs d'environ 100k

62
répondu Andrey Morozov 2016-02-05 11:29:33

les pages suivantes de la documentation élastique parlent de pagination profonde:

https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_fetch_phase.html

selon la taille de vos documents, le nombre de fragments, et le matériel que vous utilisez, 10 000 à 50 000 résultats (1 000 à 5 000 pages) deep devrait être parfaitement faisable. Mais avec assez de le processus de tri peut en effet devenir très lourd, quantité de CPU, de mémoire et de bande passante. Pour cette raison, il est fortement déconseillez le téléappel en profondeur.

16
répondu Ronald 2016-02-05 10:35:06

La bonne solution serait d'utiliser le défilement.

Cependant, si vous voulez étendre les résultats search retourne au-delà de 10.000 résultats, vous pouvez le faire facilement avec Kibana:

allez à Dev Tools et postez simplement ce qui suit à votre index (votre_index_name), spécifiant ce qui serait la nouvelle fenêtre de résultat max

enter image description here

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

si toutes bien, vous devriez voir la réponse de succès suivante:

{
  "acknowledged": true
}
14
répondu Guy Dubrovski 2017-06-11 23:38:50

utilisez L'API de défilement pour obtenir plus de 10000 résultats.

exemple de rouleau dans L'API ElasticSearch NEST

je l'ai utilisé comme ceci:

private static Customer[] GetCustomers(IElasticClient elasticClient)
{
    var customers = new List<Customer>();
    var searchResult = elasticClient.Search<Customer>(s => s.Index(IndexAlias.ForCustomers())
                          .Size(10000).SearchType(SearchType.Scan).Scroll("1m"));

    do
    {
        var result = searchResult;
        searchResult = elasticClient.Scroll<Customer>("1m", result.ScrollId);
        customers.AddRange(searchResult.Documents);
    } while (searchResult.IsValid && searchResult.Documents.Any());

    return customers.ToArray();
}
2
répondu Morten Holmgaard 2017-05-23 12:18:24

si vous voulez plus de 10000 résultats alors dans tous les noeuds de données l'utilisation de la mémoire sera très élevée parce qu'il doit retourner plus de résultats dans chaque requête de requête. Alors si vous avez plus de données et plus de fragments, alors fusionner ces résultats sera inefficace. Aussi es cache le contexte filter, donc encore plus de mémoire. Vous devez essayer et vous tromper combien exactement vous prenez. Si vous recevez de nombreuses requêtes dans une petite fenêtre, vous devriez faire plusieurs requêtes pour plus de 10k et les fusionner par urself dans le code, qui est censé prendre moins de mémoire d'application alors si vous augmentez la taille de la fenêtre.

0
répondu Amritendu 2017-03-11 07:42:38

2) il ne semble pas que l'API de défilement soit une option pour moi mais que je doive augmenter "index.max_result_window". Quelqu'un a une expérience avec cela?

-- > vous pouvez définir cette valeur dans les modèles d'index , es template sera applicable pour les nouveaux index seulement ,de sorte que vous devez supprimer les anciens index après la création de modèle ou attendre que de nouvelles données soient ingérées dans elasticsearch .

{ "ordre": 1, "modèle": "index_template*", "paramètre": { "index.number_of_replicas": "0", "index.number_of_shards": "1", "index.max_result_window": 2147483647 },

0
répondu Sindhu 2017-04-25 21:19:57