Как найти MAX по индексируемому свойству в запросе Neo4j Cypher - PullRequest
0 голосов
/ 27 сентября 2018

Мне нужно найти максимум для индексированного уникального целочисленного значения свойства.

Узел имеет индекс:

  • CREATE CONSTRAINT ON (n: транзакция) ASSERT n.id IS UNIQUE

Я пробовал запросы:

  • MATCH (n: транзакция) RETURN n.id ORDER BY n.id DESC LIMIT 1
  • MATCH (n: транзакция) RETURN max (n.id)

Оба запроса проходят всю проверку, а не используют индекс.

Как оптимизировать запрос для быстрого поиска максимального значения?

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Из-за известной проблемы Neo4j, упомянутой @cybersam, я реализовал временный обходной путь на стороне клиента (java) для выполнения бинарного поиска.Он находит максимальное значение с помощью до 32 запросов к одному узлу, что сокращает время выполнения до доли секунды, по сравнению с более чем минутой для исходного одиночного вызова с размером данных более ста миллионов узлов.

public int getLastTransactionId() {
    //return getInteger("MATCH (n:Transaction) RETURN n.id ORDER BY n.id DESC LIMIT 1").orElse(0);

    //Neo4j currently having issues with using inexes for ORDER or MAX
    //do binary search as a workaround
    return findMax("MATCH (n:Transaction {id:{id}}) RETURN n.id");
}

public int findMax(String query) {
    int minVal = 0;
    int maxVal = Integer.MAX_VALUE;
    while (minVal < maxVal) {
        int middle = (int) ((1L + minVal + maxVal) / 2);
        OptionalInt o = getInteger(query, Values.parameters("id", middle));
        log.debug("min:{}, max:{}, middle:{}, o:{}", minVal, maxVal, middle, o);
        if (o.isPresent()) {
            minVal = middle;
        } else {
            maxVal = middle - 1;
        }
    }
    return maxVal;
}
0 голосов
/ 27 сентября 2018

Возможность использовать индексы для оптимизации ORDER BY запросов является существующей проблемой , и ее планируется реализовать в neo4j 3.5 - которая должна выйти к концув этом году (2018).

[EDIT]

Тем временем, чтобы избежать сканирования всех Transaction узлов, вы можете попробовать выполнить запрос диапазона, если вы знаетехорошее min значение для максимума id.Например, если последний известный максимальный «id» был 10000:

MATCH (t:Transaction)
WHERE t.id >= 10000
RETURN node.id AS id
ORDER BY id DESC
LIMIT 1

Приведенный выше запрос будет использовать индекс для быстрого поиска id values> = минимума.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...