I need to find maximum on indexed unique property integer value.
Node has an index:
I tried queries:
Both queries going through whole scan rather that use index.
How to optimize the query to quickly find maximum value?
The ability to use indexes for optimizing ORDER BY
queries is an existing issue , and is scheduled to be implemented in neo4j 3.5 -- which should be out by the end of this year (2018).
[EDIT]
In the meantime, to avoid scanning all Transaction
nodes, you can try performing a range query if you know a good min
value for the max id
. For example, if the last known max "id" was 10000:
MATCH (t:Transaction)
WHERE t.id >= 10000
RETURN node.id AS id
ORDER BY id DESC
LIMIT 1
The above query will use the index to quickly locate id
values >= the minimum.
Due to known Neo4j's issue mentioned by @cybersam I've implemented temporary workaround on client (java) end to perform binary search. It finds max value with up to 32 single node queries that reduced runtime to subsecond compared to over a minute for original single call on data size over a hundred of millions nodes.
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.