Как оптимизировать следующий запрос neo4j Cypher - PullRequest
0 голосов
/ 25 февраля 2020

Я новичок в Cypher, и у меня есть запрос ниже, чтобы найти ошибки между 2 типами источников (например). Я считаю, что синтаксически запрос выглядит нормально, но он занимает 1 минуту, чтобы выполнить набор данных всего 1 000 000 узлов. Я не использую отношения до сих пор. Может ли кто-нибудь помочь в оптимизации запроса? Спасибо.

MATCH (VW_OXSS41:VW_OrderXStatusSummary4{SourceTypeID: "1"}) 
WHERE apoc.date.parse(VW_OXSS41.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss'))>=apoc.date.parse("2020-02-10",'s',('yyyy-MM-dd')) AND apoc.date.parse(VW_OXSS41.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss'))<=apoc.date.parse("2020-02-16",'s',('yyyy-MM-dd'))
WITH VW_OXSS41.IdentifierValue as X
MATCH (VW_OXSS42:VW_OrderXStatusSummary4{SourceTypeID: "2"}) 
WHERE apoc.date.parse(VW_OXSS42.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss'))>=apoc.date.parse("2020-02-10",'s',('yyyy-MM-dd')) AND apoc.date.parse(VW_OXSS42.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss'))<=apoc.date.parse("2020-02-16",'s',('yyyy-MM-dd'))
WITH apoc.coll.disjunction(COLLECT(X), COLLECT(VW_OXSS42.IdentifierValue)) as XX
UNWIND (XX) as YY

Обновленный запрос и ошибка: -

WITH apoc.date.parse("2020-02-20",'s',('yyyy-MM-dd')) AS a, apoc.date.parse("2020-02-25",'s',('yyyy-MM-dd')) AS b
       MATCH (x:VW_OrderXStatusSummary4 {SourceTypeID: "2"}) 
       WHERE a <= apoc.date.parse(x.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b
       WITH a, b, COLLECT(x.IdentifierValue) AS X
       MATCH (y:VW_OrderXStatusSummary4 {SourceTypeID: "1"}) 
       WHERE a <= apoc.date.parse(y.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b
       WITH X, COLLECT(y.IdentifierValue) AS Y
       UNWIND apoc.coll.subtract(X,Y) AS XX
       MATCH (z:VW_OrderXStatusSummary4 {SourceTypeID: "2"}) 
       WHERE a <= apoc.date.parse(z.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b
       RETURN XX AS MISMATCHES,MAX(z.TimeStamp);
Variable `a` not defined (line 10, column 7 (offset: 551))
"WHERE a <= apoc.date.parse(z.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b"

Устранена вышеуказанная ошибка следующим образом: -

WITH apoc.date.parse("2020-02-21",'s',('yyyy-MM-dd')) AS a, apoc.date.parse("2020-02-25",'s',('yyyy-MM-dd')) AS b
MATCH (x:VW_OrderXStatusSummary4 {SourceTypeID: "2"}) 
WHERE a <= apoc.date.parse(x.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b
WITH a, b, COLLECT(x.IdentifierValue) AS X
MATCH (y:VW_OrderXStatusSummary4 {SourceTypeID: "1"}) 
WHERE a <= apoc.date.parse(y.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b
WITH X, COLLECT(y.IdentifierValue) AS Y
UNWIND apoc.coll.subtract(X,Y) AS XX
WITH XX, apoc.date.parse("2020-02-20",'s',('yyyy-MM-dd')) AS a, apoc.date.parse("2020-02-25",'s',('yyyy-MM-dd')) AS b
MATCH (z:VW_OrderXStatusSummary4 {SourceTypeID: "2"}) 
WHERE a <= apoc.date.parse(z.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b
AND XX = z.IdentifierValue
RETURN XX AS MISMATCHES,MAX(z.TimeStamp);

С правильным ожидаемым выводом как: -

+---------------------------------------------+
| MISMATCHES          | TIMESTAMP             |
+---------------------------------------------+
| "W2002201453550218" | "2020-02-21 12:00:16" |
| "W2002201453550222" | "2020-02-21 12:00:16" |
| "W2002201453550223" | "2020-02-21 09:30:36" |
| "W2002201453550224" | "2020-02-21 12:00:16" |
| "W2002201453550226" | "2020-02-21 12:00:16" |
| "W2002201453550227" | "2020-02-21 12:00:16" |
| "W2002201453550237" | "2020-02-21 12:00:16" |
| "3011WOS002978598"  | "2020-02-21 10:00:54" |
| "3011WOS002978595"  | "2020-02-21 13:00:57" |
| "0010000000006183"  | "2020-02-21 16:00:41" |
| "W2002181111547439" | "2020-02-21 04:00:34" |
| "11"                | "2020-02-21 16:00:41" |
| "10112787861P1458"  | "2020-02-21 10:00:54" |
+---------------------------------------------+

Хотите знать, есть ли лучший подход?

1 Ответ

1 голос
/ 26 февраля 2020
  1. Вам не следует делать декартово произведение между результатами двух ваших MATCH предложений. Допустим, два предложения MATCH обычно возвращали бы N и M узлов соответственно при выполнении в своих собственных запросах. Поскольку ваш запрос объединяет эти два предложения MATCH так, как он это делает, ваше второе предложение MATCH фактически выполняет N*M совпадения (и создает N*M строки результатов).

  2. Вам необходимо убедиться, что вы создали индекс для :VW_OrderXStatusSummary4(SourceTypeID). Это оптимизирует поиски, выполняемые предложениями MATCH.

  3. Вы можете упростить код Cypher, чтобы избежать дублирования вызовов функций.

После создав указанный выше индекс, попробуйте следующее:

WITH apoc.date.parse("2020-02-10",'s',('yyyy-MM-dd')) AS a, apoc.date.parse("2020-02-16",'s',('yyyy-MM-dd')) AS b
MATCH (x:VW_OrderXStatusSummary4 {SourceTypeID: "1"}) 
WHERE a <= apoc.date.parse(x.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b
WITH a, b, COLLECT(x.IdentifierValue) AS X
MATCH (y:VW_OrderXStatusSummary4 {SourceTypeID: "2"}) 
WHERE a <= apoc.date.parse(y.TimeStamp,'s',('yyyy-MM-dd HH:mm:ss')) <= b
WITH X, COLLECT(y.IdentifierValue) AS Y
UNWIND apoc.coll.disjunction(X, Y) AS YY
...

Выполнение операции COLLECT(x.IdentifierValue) в первом предложении WITH заставляет его вернуть все узлы x в одной строке результатов (вместо N строки результата). Это позволяет второму MATCH избежать проблемы декартовых произведений.

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