Максимальное ограничение на количество значений, которые я могу указать в фильтре идентификаторов или в общем случае запроса?

В elasticsearch, каков максимальный предел для указания значения в количестве значений, которое может быть выполнено совпадение? Я где-то читал, что это 1024, но также настраивается. Это правда? И как это влияет на производительность?

curl -XPOST 'localhost:9200/my_index/_search?pretty' -d '{
  "query": {
    "filtered": {
      "filter": {
        "not": {
          "ids": {
            "type": "my_type",
            "values": ["1", "2", "3"]
}}}}}}'

Сколько значений можно задать в этом массиве? Каков предел? Если это настраивается, что влияет на производительность при увеличении лимита?

Ответы

Ответ 1

Я не думаю, что есть какие-либо ограничения, установленные Elaticsearch или Lucene явно. Однако предел, который вы могли бы нанести, - это тот, который установлен JDK на месте.

Чтобы доказать мое утверждение выше, я посмотрел исходный код Elasticsearch:

/**
 * 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;
}

И это число (Integer.MAX_VALUE - 8) равно 2147483639. Таким образом, это будет теоретический максимальный размер этого массива.

Я тестировал локально в своем экземпляре ES массив из 150000 элементов. И здесь последствия производительности: конечно, вы получите снижение производительности, чем больше массив получает. В моем простом тестировании с идентификаторами 150 КБ я получил время выполнения 800 мс. Но все зависит от процессора, памяти, нагрузки, данных, сопоставления данных и т.д. Лучше всего было бы проверить это на самом деле.

ОБНОВЛЕНО декабрь 2016: этот ответ применяется к версии Elasticsearch, существующей в конце 2014 года, то есть в ветки 1.x. Последний доступный в то время был 1.4.x.

Ответ 2

Да! Количество значений в полях настраивается. По умолчанию он ограничен 1024. Вы можете настроить его в файле elasticsearch.yml.

indices.query.bool.max_clause_count: 10000

Примечание. Увеличение лимита приведет к высокой загрузке памяти и процессора.

Подробнее см. в этих ссылках:

https://groups.google.com/forum/#!topic/elasticsearch/LqywKHKWbeI

https://github.com/elasticsearch/elasticsearch/issues/482

http://elasticsearch-users.115913.n3.nabble.com/index-query-bool-max-clause-count-Setting-and-TermsQueryParser-td3050751.html

http://elasticsearch-users.115913.n3.nabble.com/Query-string-length-limit-td4054066.html