Issue 1:
The current implementation of TransactionImpl#nodesByLabelAndProperties will scan all nodes with a label if there are no indices that include all of the query properties and no other properties. It should be optimized to use partially matching indices (indices which have a subset of the query properties, or which have extra properties, or both), and further filter matches if necessary.

This method is used by several methods on Transaction, including findNodes(Label, Map<String, Object>), findNodes(Label, String, Object), etc. This can result in significant performance problems when using these methods with a set of properties that does not match an index exactly.

Neo4j Version: current (applies to at least 4.2.x, 4.1.x)

Operating System: all

API: Java API

Steps to reproduce

Create an index on a node label: CREATE INDEX FOR (n:Person) ON (n.given_name)

Create a large amount of data

Try to find nodes using transaction.findNodes(Label.label("Person"), Map.of("given_name", "foo", "surname", "bar"))

Expected behavior

The partially matching index for given_name should be used, resulting in a performant fetch operation

Actual behavior

The index for given_name will not be used, which results in scanning all nodes (this can be verified by setting a breakpoint on TransactionImpl line 771, where it returns return getNodesByLabelAndPropertyWithoutIndex( labelId, queries );)

Issue 2:
Hello everybody, I'm having issue with MERGE with Constrains in 2.0.0-M06

Basically, I need to insert buge amount of tweets with relationships between them into Neo4j via REST API's Batch endpoint, approx 5k/s

Sometime, it's a single node creation for a tweet; sometime, I need to create both parent and child nodes first and then create relationship.

My Schema

[code]

neo4j-sh (0)$ schema

==> Indexes

==> ON :REPLY(created_at) ONLINE

==> ON :REPLY(ids) ONLINE (for uniqueness constraint)

==> ON :RETWEET(created_at) ONLINE

==> ON :RETWEET(ids) ONLINE (for uniqueness constraint)

==> ON :Status(userId) ONLINE

==> ON :Status(statusId) ONLINE (for uniqueness constraint)

==>

==> Constraints

==> ON (status:Status) ASSERT status.statusId IS UNIQUE

==> ON (retweet:RETWEET) ASSERT retweet.ids IS UNIQUE

==> ON (reply:REPLY) ASSERT reply.ids IS UNIQUE

[/code]

ISSUE #ONE: MERGE doesn't ALWAYS work with Constrains properly (or Constrains doesn't work with MERGE properly). (random exception)

Here are my test cases:

Two MERGE's and one CREATE UNIQUE

When I tried to add two tweets with one relationship between them, I got a exception, which complaining existing node for the child

neo4j-sh (0)$ MERGE (parent:Status {statusId:385813052047626240, userId:466042117}) MERGE (child:Status {statusId:385814827270017024, userId:1130050117}) CREATE UNIQUE parent-[relationship:REPLY {ids:'385813052047626240_385814827270017024', created_at:'Thu Oct 03 14:13:17 ADT 2013' }]->child;

==> CypherExecutionException: Node 270100 already exists with label Status and property "statusId"=[385814827270017024]

Then, I broke down my joint query to small pieces. So first, I tried to create the parent node with a single MERGE, it works as expected

neo4j-sh (0)$ MERGE (parent:Status {statusId:385813052047626240, userId:466042117}) RETURN parent;

==> +------------------------------------------------------------+

==> | parent |

==> +------------------------------------------------------------+

==> | Node[284599]{userId:466042117,statusId:385813052047626240} |

==> +------------------------------------------------------------+

==> 1 row

==> Nodes created: 1

==> Properties set: 2

==> Labels added: 1

==> 4 ms

neo4j-sh (0)$ MERGE (parent:Status {statusId:385813052047626240, userId:466042117}) RETURN parent;

==> +------------------------------------------------------------+

==> | parent |

==> +------------------------------------------------------------+

==> | Node[284599]{statusId:385813052047626240,userId:466042117} |

==> +------------------------------------------------------------+

==> 1 row

==> 1 ms

Next, I tried to create the child node with a single MERGE, but it failed like step 1.

neo4j-sh (0)$ MERGE (child:Status {statusId:385814827270017024, userId:1130050117}) RETURN child;

==> CypherExecutionException: Node 270100 already exists with label Status and property "statusId"=[385814827270017024]

I tried MERGE on few more exsting nodes, some worked, some failed.

I thought it may cased by existing relationship, so I checked both direction of a problemtic node, which turns out it doesn't have any existing relationship in place.

neo4j-sh (0)$ MERGE (child:Status {statusId:385814902293553153, userId:1725656978});

==> CypherExecutionException: Node 301777 already exists with label Status and property "statusId"=[385814902293553153]

neo4j-sh (0)$ START a = node(301777) MATCH a-[r]->b RETURN b;

==> +---+

==> | b |

==> +---+

==> +---+

==> 0 row

==> 1 ms

neo4j-sh (0)$ START a = node(301777) MATCH b-[r]->a RETURN b;

==> +---+

==> | b |

==> +---+

==> +---+

==> 0 row

==> 0 ms

ISSUE #TWO: Constrained property on relationship doesn't work with CREATE UNIQUE properly, I was able to create duplicate reltionships with same constrained property.

First, I have created two nodes and one relationship between them. (MERGE with Constrains worked this time :)), the results below is to show I have them in DB

neo4j-sh (0)$ MERGE (parent:Status {statusId:1001, userId:901}) MERGE (child:Status {statusId:1002, userId:902}) CREATE UNIQUE parent-[relationship:RETWEET {ids:'1001_1002', created_at:'Mon Nov 04 14:37:56 AST 2013' }]->child RETURN parent, relationship, child;

==> +------------------------------------------------------------------------------------------------------------------------------------------------+

==> | parent | relationship | child |

==> +------------------------------------------------------------------------------------------------------------------------------------------------+

==> | Node[1]{statusId:1001,userId:901} | :RETWEET[0]{ids:"1001_1002",created_at:"Mon Nov 04 14:37:56 AST 2013"} | Node[2]{statusId:1002,userId:902} |

==> +------------------------------------------------------------------------------------------------------------------------------------------------+

==> 1 row

==> 13 ms

Then, I modified the script a bit, where I changed year in created_at from 2013 to 2019, and I expect this to fail, coz the unique constrain is on ids, but the script created a new relationship between same nodes, so it ends up I have two relationships with same constrained ids between two same nodes.

neo4j-sh (0)$ MERGE (parent:Status {statusId:1001, userId:901}) MERGE (child:Status {statusId:1002, userId:902}) CREATE UNIQUE parent-[relationship:RETWEET {ids:'1001_1002', created_at:'Mon Nov 04 14:37:56 AST 2019' }]->child RETURN parent, relationship, child;

==> +-----------------------------------------------------------------------------------------------------------------------------------------------------+

==> | parent | relationship | child |

==> +-----------------------------------------------------------------------------------------------------------------------------------------------------+

==> | Node[1]{statusId:1001,userId:901} | :RETWEET[224428]{ids:"1001_1002",created_at:"Mon Nov 04 14:37:56 AST 2019"} | Node[2]{statusId:1002,userId:902} |

==> +-----------------------------------------------------------------------------------------------------------------------------------------------------+

==> 1 row

==> Relationships created: 1

==> Properties set: 2

==> 12 ms

neo4j-sh (0)$ START parent=node(1) MATCH parent-[relationship]->(child) WHERE child.statusId=1002 RETURN parent,relationship,child;

==> +-----------------------------------------------------------------------------------------------------------------------------------------------------+

==> | parent | relationship | child |

==> +-----------------------------------------------------------------------------------------------------------------------------------------------------+

==> | Node[1]{statusId:1001,userId:901} | :RETWEET[0]{ids:"1001_1002",created_at:"Mon Nov 04 14:37:56 AST 2013"} | Node[2]{statusId:1002,userId:902} |

==> | Node[1]{statusId:1001,userId:901} | :RETWEET[224428]{ids:"1001_1002",created_at:"Mon Nov 04 14:37:56 AST 2019"} | Node[2]{statusId:1002,userId:902} |

==> +-----------------------------------------------------------------------------------------------------------------------------------------------------+

==> 2 rows

==> 7 ms

Any help would be much appreciated!!!!! Thank you!

Jack