neo4j для обнаружения мошенничества - эффективная структура данных

Я пытаюсь улучшить систему обнаружения мошенничества для коммерческого сайта. Мы имеем дело с прямыми банковскими операциями, поэтому мошенничество - это риск, которым мы должны управлять. Недавно я узнал о построении графиков баз данных и могу понять, как они относятся к этим проблемам. Итак, за последние пару дней я настроил neo4j и проанализировал в нем наши данные: пример

Моя интуиция заключалась в том, чтобы создать узел для каждого заказа и узел для каждого фрагмента данных, связанных с ним, а затем соединить их все вместе. Как это:

MATCH (w:Wallet),(i:Ip),(e:Email),(o:Order) 
WHERE w.wallet="ex" AND i.ip="ex" AND e.email="ex" AND o.refcode="ex" 
CREATE (w)-[:USED]->(o),(i)-[:USED]->(o),(e)-[:USED]->(o)

Но этот запрос выполняется очень медленно по мере увеличения размера базы данных (я полагаю, потому что он должен искать весь набор данных для узлов, которые я запрашиваю). Для выполнения запроса также требуется много времени:

START a=node(179) 
MATCH (a)-[:USED*]-(d) 
WHERE EXISTS(d.refcode) 
RETURN distinct d

Это предназначено для извлечения всех заказов, которые связаны с начальной точкой. Я очень новичок в Cypher (<24 часа), и мне особенно трудно искать решения.

Существуют ли какие-либо конкретные проблемы со структурой данных или запросами, которые я могу решить для повышения производительности? В идеале это нужно завершить в течение нескольких секунд, как я и ожидал от базы данных SQL. На данный момент у нас около 17 000 узлов.

1 ответ

Всегда хорошая идея, чтобы полностью прочитать руководство для разработчиков.

Для ускорения поиска узлов по свойству вам обязательно нужно создать индексы или уникальные ограничения (в зависимости от того, должно ли свойство быть уникальным для метки / значения).

После того как вы создали нужные индексы и ограничения, они будут использоваться вашим запросом для ускорения ваших совпадений.

START используется только для устаревших индексов, и для последних версий Neo4j вы должны использовать вместо него MATCH. Если вы соответствуете на основе внутреннего идентификатора, вы можете использовать MATCH (n) WHERE id(n) = xxx,

Имейте в виду, что вам не следует сохранять идентификаторы узлов за пределами Neo4j для поиска в будущих запросах, поскольку идентификаторы внутренних узлов могут использоваться повторно при удалении и создании узлов, поэтому идентификатор, который когда-то ссылался на удаленный узел, может в конечном итоге указывать в совершенно другой узел.

Использование меток в ваших запросах должно помочь вашей производительности. В запросе, который вы задали для поиска заказов, Neo4j должен проверить каждый конечный узел на вашем пути, чтобы узнать, существует ли свойство. Доступ к свойствам имеет тенденцию быть дорогим, особенно когда вы используете сопоставление переменной длины, поэтому лучше ограничить узлы, которые вы хотите, по метке.

MATCH (a)-[:USED*]-(d:Order)
WHERE id(a) = 179 
RETURN distinct d

На больших графиках совпадение переменной длины может начать замедляться, поэтому вы можете повысить производительность, установив процедуры APOC и используя процедуру Path Expander, чтобы собрать все узлы подграфа и отфильтровать их до узлов Order.

MATCH (a)
WHERE id(a) = 179
CALL apoc.path.expandConfig(a, {bfs:true, uniqueness:"NODE_GLOBAL"}) YIELD path
RETURN LAST(NODES(path)) as d
WHERE d:Order
Другие вопросы по тегам