Я новичок в Neo4j. На данный момент я оцениваю использование Neo4j для одного из наших вариантов использования. У меня возникают проблемы, когда я пытаюсь объединить с большим количеством узлов.Neo4j: медленная агрегация с большим количеством узлов
Мы используем Neo4j для хранения посетителей, которые подали голоса, относящиеся к разным категориям. В голосовании есть место и реферер, который я смоделировал как отдельные узлы, чтобы «повторно использовать» их.
Это примерно то, что моя схема выглядит (Node Голосуйте имеет дополнительные отношения, которые я здесь опуская):
(Visitor {id})-[VOTED]->(Vote)-[RELATES_TO]->(Category {name})
с индексом на Vistor.id и Category.name
Наш набор данных довольно велик , поэтому я начал тестировать свою схему с 4 миллионами голосов и 3 миллионами посетителей. Голоса относятся к 18 различным категориям.
Я хочу иметь возможность делать скопления. Например, мне нужно получить количество отдельных посетителей, которые проголосовали за категории «А» и «CATEGORY B».
MATCH (c:Category)<-[:PARENT*0..3]-(child:Category)<-[:RELATES_TO]-(v:Vote)<-[:VOTED]-(visitor:Visitor)
WHERE c.name = 'Category A'
WITH visitor
MATCH (c:Category)<-[:RELATES_TO]-(v:Vote)<-[:VOTED]-(visitor)
WHERE c.name = 'Category B'
RETURN count(distinct(visitor.id)) as Cat_A_and_B_lovers
Это занимает почти 30 секунд
Я хотел бы также, чтобы иметь возможность получить все категории и количество различных голосов:
MATCH (n:Category)<-[:RELATES_TO]-(:Vote)<-[:VOTED]-(v:Visitor)
RETURN n.name as category, count(DISTINCT v) as count;
Это занимает 13 секунд.
Возможно ли улучшить эти тайминги, или Neo4j просто не подходит для такого анализа?
Мы также анализируем данные на уровне каждого посетителя, но также хотели бы иметь возможность делать эти агрегации.
Мои настройки:
Linux, 4 ядра 14GB
Noe4j сообщество версия
neo4j.conf:
dbms.memory.heap.initial_size = 2G
dbms.memory.heap.max_size = 10G
dbms.memory.pagecache.size = 10g
- ОБНОВЛЕНИЕ 15/02
Следующие предложения Майкла я был способный улучшить время выполнения обоих запросов. Мой первый вопрос: выход
PROFILE MATCH (n:Category)<-[:RELATES_TO]-()<-[:VOTED]-(v:Visitor)
WITH n, count(DISTINCT v) as count
RETURN n.name as category, count
ПРОФИЛЬ:
9964 мс
Компилятор CYPHER 3,1
Планировщик COST
Продолжительность INTERPRETED
+-------------------+----------------+---------+---------+--------------------------------------+------------------------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+-------------------+----------------+---------+---------+--------------------------------------+------------------------------------+
| +ProduceResults | 1545 | 18 | 0 | category, count | category, count |
| | +----------------+---------+---------+--------------------------------------+------------------------------------+
| +Projection | 1545 | 18 | 18 | category -- count, n | {category : n.name, count : count} |
| | +----------------+---------+---------+--------------------------------------+------------------------------------+
| +EagerAggregation | 1545 | 18 | 0 | count -- n | n |
| | +----------------+---------+---------+--------------------------------------+------------------------------------+
| +Filter | 2386269 | 4114784 | 4114784 | anon[19], anon[35], anon[37], n, v | v:Visitor |
| | +----------------+---------+---------+--------------------------------------+------------------------------------+
| +Expand(All) | 2386269 | 4114784 | 8229568 | anon[37], v -- anon[19], anon[35], n |()<-[:VOTED]-(v) |
| | +----------------+---------+---------+--------------------------------------+------------------------------------+
| +Expand(All) | 4113784 | 4114784 | 4114807 | anon[19], anon[35] -- n | (n)<-[:RELATES_TO]-() |
| | +----------------+---------+---------+--------------------------------------+------------------------------------+
| +NodeByLabelScan | 23 | 23 | 24 | n | :Category |
+-------------------+----------------+---------+---------+--------------------------------------+------------------------------------+
Это займет почти 10 секунд. Мне нужно было бы получить его ниже 1 секунды. Возможно ли это вообще (используя neo4j)?
Это может быть лучше подходит для обзора кода. Stack Overflow здесь, чтобы помочь с реальной проблемой, означающей «исправление чего-то, что не работает», в отличие от «улучшения чего-то, что работает». –
Как насчет индекса? –
У меня есть индекс на Vistor.id и Category.name. – Johanna