Dans elasticsearch, quelle est la limite maximale pour spécifier la valeur du nombre de valeurs sur lesquelles une correspondance peut être effectuée? J'ai lu quelque part qu'il est 1024 mais est également configurable. Est-ce vrai? Et comment cela affecte-t-il les performances?
curl -XPOST 'localhost:9200/my_index/_search?pretty' -d '{
"query": {
"filtered": {
"filter": {
"not": {
"ids": {
"type": "my_type",
"values": ["1", "2", "3"]
}}}}}}'
Combien de valeurs puis-je spécifier dans ce tableau? Quelle est la limite? S'il est configurable, quel est l'impact sur les performances de l'augmentation de la limite?
Je ne pense pas qu'il y ait explicitement de limite fixée par Elaticsearch ou Lucene. La limite que vous pourriez atteindre, cependant, est celle fixée par le JDK.
Pour prouver ma déclaration ci-dessus, j'ai regardé le code source d'Elasticsearch:
lorsque la demande arrive il y a un analyseur qui analyse le tableau des identifiants . Tout ce qu'il utilise est un ArrayList
. Ceci est ensuite transmis à Lucene, qui à son tour utilise une liste.
il s'agit de la classe Lucene TermsFilter (ligne # 84) qui obtient la liste des IDS d'Elasticsearch dans une liste.
code source de la classe ArrayList
à partir d'Oracle JDK 1.7.0_67:
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
...
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
...
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
Et ce nombre (Integer.MAX_VALUE - 8
) est 2147483639
. Donc, ce serait la taille maximale théorique de ce tableau.
J'ai testé localement dans mon instance ES un tableau de 150000 éléments. Et voici les implications en termes de performances: bien sûr, vous obtiendrez des performances dégradantes plus la baie sera grande. Dans mon test simple avec 150k ids, j'ai obtenu un temps d'exécution de 800 ms. Mais, tout dépend du processeur, de la mémoire, de la charge, de la taille des données, du mappage des données, etc. Le mieux serait que vous testiez réellement cela.
MISE À JOUR décembre 2016 : cette réponse s'applique à la version Elasticsearch qui existait fin 2014, c'est-à-dire dans la branche 1.x. La dernière version disponible à l'époque était la 1.4.x.
Oui! Le nombre de valeurs dans les champs est configurable. Par défaut, il est limité à 1024. Vous pouvez le configurer dans le fichier elasticsearch.yml.
indices.query.bool.max_clause_count: 10000
Remarque: l'augmentation de la limite entraînera une utilisation élevée de la mémoire et du processeur.
Reportez-vous à ces liens pour plus d'informations:
https://groups.google.com/forum/#!topic/elasticsearch/LqywKHKWbeI
https://github.com/elasticsearch/elasticsearch/issues/482
http://elasticsearch-users.115913.n3.nabble.com/Query-string-length-limit-td4054066.html
Une limitation au niveau de l'index du nombre de termes dans une requête de termes sera introduite dans ES 7. .
Le paramètre est index.max_terms_count avec une valeur par défaut de 65536.
De la docs pour la version 6.4 :
L'exécution d'une requête de requête de termes avec beaucoup de termes peut être assez lente, car chaque terme supplémentaire nécessite un traitement et une mémoire supplémentaires. Pour se prémunir contre cela, le nombre maximal de termes pouvant être utilisés dans une requête de termes à la fois directement ou par le biais d'une recherche a été limité à 65536 . Ce maximum par défaut peut être modifié pour un index particulier avec le paramètre d'index index.max_terms_count.