2016-03-31 2 views
1

Ich habe ein Problem in einer Neo4j Abfrage. Angenommen, ich habe einen Knotentyp namens App. Die App-Knoten haben die Felder "m_id" und "info". Ich möchte eine Abfrage erstellen, um eine Beziehung zwischen den Knoten zu erstellen, wo das Feld "info" gleich ist.Leistung von CYPHER 2.3 in Neo4j Abfrage

Dies ist die Abfrage:

MATCH (a:App {m_id:'SOME_VALUE' }),(b:App {info: a.info}) WHERE ID(a)<>ID(b) AND NOT (b)-[:INFO]->(a) MERGE (a)-[r:INFO]->(b) RETURN b.m_id; 

Ich habe auch Indizes für beide Felder:

CREATE CONSTRAINT ON (a:App) ASSERT a.m_id IS UNIQUE; 
CREATE INDEX ON :App(info); 

Aber die Sache ist ich sehr langsame Abfragen erhalten, mit Zugang in allen Datensätzen der App Knoten.

Dies ist das Profil der Abfrage:

+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 
| Operator  | Rows | DB Hits | Identifiers  | Other                               | 
+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 
| +ColumnFilter |  0 |  0 | b.m_id   | keep columns b.m_id                           | 
| |    +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 
| +Extract  |  0 |  0 | a, b, b.m_id, r | b.m_id                               | 
| |    +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 
| +Merge(Into) |  0 |  1 | a, b, r   | (a)-[r:INFO]->(b)                            | 
| |    +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 
| +Eager  |  0 |  0 | a, b   |                                | 
| |    +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 
| +Filter  |  0 | 2000000 | a, b   | Ands(b.info == a.info, NOT(IdFunction(a) == IdFunction(b)), NOT(nonEmpty(PathExpression((b)-[anon[104]:INFO]->(a), true)))) | 
| |    +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 
| +SchemaIndex | 184492 | 1000000 | a, b   | { AUTOSTRING0}; :App(m_id)                         | 
| |    +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 
| +NodeByLabel | 184492 | 1000001 | b    | :App                               | 
+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ 

Antwort

1

Versuchen a selbst zu finden, mit einer WITH Klausel a.info in eine temporäre Variable zu setzen, die für b durch eine separate MATCH Klausel verwendet wird, wie in:

MATCH (a:App { m_id:'SOME_VALUE' }) 
WITH a, a.info AS a_info 
MATCH (b:App { info: a_info }) 
WHERE a <> b AND NOT (b)-[:INFO]->(a) 
MERGE (a)-[r:INFO]->(b) 
RETURN b.m_id; 

Es scheint, dass Indizes beim Vergleich der Eigenschaften von 2 Knoten nicht verwendet werden. Die Verwendung von a_info beseitigt diese Behinderung.

Wenn das Profil der oben zeigt, dass eine oder beide Indizes nicht, können Sie versuchen, Indexhinweise Zugabe verwendet:

MATCH (a:App { m_id:'SOME_VALUE' }) 
USING INDEX a:App(m_id) 
WITH a, a.info AS a_info 
MATCH (b:App { info: a_info }) 
USING INDEX b:App(info) 
WHERE a <> b AND NOT (b)-[:INFO]->(a) 
MERGE (a)-[r:INFO]->(b) 
RETURN b.m_id; 
+0

Es ist gut genug, um es in zwei Spielen aufzuteilen. Keine Notwendigkeit für Zwischen WITH oder Ausdruck Alias ​​in 2.3 –

+0

Ihre Lösung funktioniert auch. –

0

ich eine Lösung herauszufinden OPTIONAL MATCH mit:

MATCH (a: App {m_id: 'SOME_VALUE'}) OPTIONALES MATCH (a), (b: App {info: a.info}) WO ID (a) <> ID (b) UND NICHT (b) - [: INFO] -> (a) MERGE (a) - [r: INFO] -> (b) ZURÜCK b.m_id;

Dies ist das Profil der Abfrage:

+----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| Operator  | Rows | DB Hits | Identifiers  | Other                          | 
+----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| +ColumnFilter | 0 |  0 | b.m_id   | keep columns b.m_id                      | 
| |    +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| +Extract  | 0 |  0 | a, b, b.m_id, r | b.m_id                          | 
| |    +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| +Merge(Into) | 0 |  1 | a, b, r   | (a)-[r:INFO]->(b)                       | 
| |    +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| +Eager   | 0 |  0 | a, b   |                           | 
| |    +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| +OptionalMatch | 0 |  0 | a, b   |                           | 
| |\    +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| | +Filter  | 0 |  0 | a, b   | Ands(NOT(IdFunction(a) == IdFunction(b)), NOT(nonEmpty(PathExpression((b)-[anon[109]:INFO]->(a), true)))) | 
| | |   +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| | +SchemaIndex | 0 |  0 | a, b   | a.info; :App(info)                      | 
| | |   +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| | +Argument | 0 |  0 | a    |                           | 
| |    +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+ 
| +SchemaIndex | 0 |  1 | a    | { AUTOSTRING0}; :App(m_id)                    | 
+----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+