ОБНОВЛЕНИЕ: Последующий отчет blog post опубликован.
Это распространенный вопрос, когда мы моделируем наборы данных для клиентов и типичный пример использования для активных/неактивных объектов.
Это немного обратная связь о том, что я испытал действительно для Neo4j2.1.6:
Пункта 1. Вы не будете иметь разницы в дБ доступы между согласованием на этикетке или на индексированном имущество и возврате узлы
Пункт 2. разница будет встречаться, когда такие узлы находятся в конце узора, например
MATCH (n:User {id:1})
WITH n
MATCH (n)-[:WRITTEN]->(post:Post)
WHERE post.published = true
RETURN n, collect(post) as posts;
-
PROFILE MATCH (n:User) WHERE n._id = 'c084e0ca-22b6-35f8-a786-c07891f108fc'
> WITH n
> MATCH (n)-[:WRITTEN]->(post:BlogPost)
> WHERE post.active = true
> RETURN n, size(collect(post)) as posts;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| n | posts |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Node[118]{_id:"c084e0ca-22b6-35f8-a786-c07891f108fc",login:"joy.wiza",password:"7425b990a544ae26ea764a4473c1863253240128",email:"[email protected]"} | 1 |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row
ColumnFilter(0)
|
+Extract
|
+ColumnFilter(1)
|
+EagerAggregation
|
+Filter
|
+SimplePatternMatcher
|
+SchemaIndex
+----------------------+------+--------+----------------------+----------------------------------------------------------------------------+
| Operator | Rows | DbHits | Identifiers | Other |
+----------------------+------+--------+----------------------+----------------------------------------------------------------------------+
| ColumnFilter(0) | 1 | 0 | | keep columns n, posts |
| Extract | 1 | 0 | | posts |
| ColumnFilter(1) | 1 | 0 | | keep columns n, AGGREGATION153 |
| EagerAggregation | 1 | 0 | | n |
| Filter | 1 | 3 | | (hasLabel(post:BlogPost(1)) AND Property(post,active(8)) == { AUTOBOOL1}) |
| SimplePatternMatcher | 1 | 12 | n, post, UNNAMED84 | |
| SchemaIndex | 1 | 2 | n, n | { AUTOSTRING0}; :User(_id) |
+----------------------+------+--------+----------------------+----------------------------------------------------------------------------+
Total database accesses: 17
В этом случае Cypher не будет использовать индекс :Post(published)
.
Таким образом, использование этикеток является более эффективным в том случае, если у вас есть ярлык ActivePost, например. :
neo4j-sh (?)$ PROFILE MATCH (n:User) WHERE n._id = 'c084e0ca-22b6-35f8-a786-c07891f108fc'
> WITH n
> MATCH (n)-[:WRITTEN]->(post:ActivePost)
> RETURN n, size(collect(post)) as posts;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| n | posts |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Node[118]{_id:"c084e0ca-22b6-35f8-a786-c07891f108fc",login:"joy.wiza",password:"7425b990a544ae26ea764a4473c1863253240128",email:"[email protected]"} | 1 |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row
ColumnFilter(0)
|
+Extract
|
+ColumnFilter(1)
|
+EagerAggregation
|
+Filter
|
+SimplePatternMatcher
|
+SchemaIndex
+----------------------+------+--------+----------------------+----------------------------------+
| Operator | Rows | DbHits | Identifiers | Other |
+----------------------+------+--------+----------------------+----------------------------------+
| ColumnFilter(0) | 1 | 0 | | keep columns n, posts |
| Extract | 1 | 0 | | posts |
| ColumnFilter(1) | 1 | 0 | | keep columns n, AGGREGATION130 |
| EagerAggregation | 1 | 0 | | n |
| Filter | 1 | 1 | | hasLabel(post:ActivePost(2)) |
| SimplePatternMatcher | 1 | 4 | n, post, UNNAMED84 | |
| SchemaIndex | 1 | 2 | n, n | { AUTOSTRING0}; :User(_id) |
+----------------------+------+--------+----------------------+----------------------------------+
Total database accesses: 7
Точка 3. Всегда используйте этикетки для позитивов, то есть для случая выше, имея проект ярлыка заставит вас выполнить следующий запрос:
MATCH (n:User {id:1})
WITH n
MATCH (n)-[:POST]->(post:Post)
WHERE NOT post :Draft
RETURN n, collect(post) as posts;
Это означает, что Cypher будет открывать каждый заголовки меток узлов и сделать фильтр на нем.
Пункт 4. Избегайте имея необходимость согласования на нескольких лейблах
MATCH (n:User {id:1})
WITH n
MATCH (n)-[:POST]->(post:Post:ActivePost)
RETURN n, collect(post) as posts;
neo4j-sh (?)$ PROFILE MATCH (n:User) WHERE n._id = 'c084e0ca-22b6-35f8-a786-c07891f108fc'
> WITH n
> MATCH (n)-[:WRITTEN]->(post:BlogPost:ActivePost)
> RETURN n, size(collect(post)) as posts;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| n | posts |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Node[118]{_id:"c084e0ca-22b6-35f8-a786-c07891f108fc",login:"joy.wiza",password:"7425b990a544ae26ea764a4473c1863253240128",email:"[email protected]"} | 1 |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row
ColumnFilter(0)
|
+Extract
|
+ColumnFilter(1)
|
+EagerAggregation
|
+Filter
|
+SimplePatternMatcher
|
+SchemaIndex
+----------------------+------+--------+----------------------+---------------------------------------------------------------+
| Operator | Rows | DbHits | Identifiers | Other |
+----------------------+------+--------+----------------------+---------------------------------------------------------------+
| ColumnFilter(0) | 1 | 0 | | keep columns n, posts |
| Extract | 1 | 0 | | posts |
| ColumnFilter(1) | 1 | 0 | | keep columns n, AGGREGATION139 |
| EagerAggregation | 1 | 0 | | n |
| Filter | 1 | 2 | | (hasLabel(post:BlogPost(1)) AND hasLabel(post:ActivePost(2))) |
| SimplePatternMatcher | 1 | 8 | n, post, UNNAMED84 | |
| SchemaIndex | 1 | 2 | n, n | { AUTOSTRING0}; :User(_id) |
+----------------------+------+--------+----------------------+---------------------------------------------------------------+
Total database accesses: 12
Это приведет к тому же процессу для Cypher, что на пункте 3.
Пункт 5. Если возможно , избегайте необходимости согласования на этикетках с помощью хорошо набранных названных взаимосвязей
MATCH (n:User {id:1})
WITH n
MATCH (n)-[:PUBLISHED]->(p)
RETURN n, collect(p) as posts
-
MATCH (n:User {id:1})
WITH n
MATCH (n)-[:DRAFTED]->(post)
RETURN n, collect(post) as posts;
neo4j-sh (?)$ PROFILE MATCH (n:User) WHERE n._id = 'c084e0ca-22b6-35f8-a786-c07891f108fc'
> WITH n
> MATCH (n)-[:DRAFTED]->(post)
> RETURN n, size(collect(post)) as posts;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| n | posts |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Node[118]{_id:"c084e0ca-22b6-35f8-a786-c07891f108fc",login:"joy.wiza",password:"7425b990a544ae26ea764a4473c1863253240128",email:"[email protected]"} | 3 |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row
ColumnFilter(0)
|
+Extract
|
+ColumnFilter(1)
|
+EagerAggregation
|
+SimplePatternMatcher
|
+SchemaIndex
+----------------------+------+--------+----------------------+----------------------------------+
| Operator | Rows | DbHits | Identifiers | Other |
+----------------------+------+--------+----------------------+----------------------------------+
| ColumnFilter(0) | 1 | 0 | | keep columns n, posts |
| Extract | 1 | 0 | | posts |
| ColumnFilter(1) | 1 | 0 | | keep columns n, AGGREGATION119 |
| EagerAggregation | 1 | 0 | | n |
| SimplePatternMatcher | 3 | 0 | n, post, UNNAMED84 | |
| SchemaIndex | 1 | 2 | n, n | { AUTOSTRING0}; :User(_id) |
+----------------------+------+--------+----------------------+----------------------------------+
Total database accesses: 2
будет более производительным, так как он будет использовать всю мощность на графике и просто следовать отношениям от узла, в результате чего не больше дб доступа, чем соответствующий узел пользователя и, таким образом, без фильтрации на этикетках.
Это был мой 0,02 €
Я действительно не знаю, но я думаю, что ярлык будет более эффективным. Если вы используете метку, вы можете исключить все узлы '(: Tweet), даже не сопоставляя их. Если вы используете метод свойства на узле '(: Tweet)', то ваш матч по-прежнему будет содержать метку 'Tweet' в матче. В реляционных или каталогах миров я не думаю, что вы бы указали значение свойства, поскольку оно имело бы низкую избирательность. Однако мне интересно узнать ответы. –