Самый низкий общий предок с algo.shortestPath.stream и cypher projection - PullRequest
0 голосов
/ 08 ноября 2019

neo4j-рабочий стол: 1.2.2 и neo4j-браузер: 3.2.24 (p2neo v.4) APOC: 3.5.0.5 Graph-Algo: 3.5.11.0 GraphQL: 3.5.0.4 Размер графика: 159 760 узлов, 389 554отношения

Привет, я хочу найти наименьшего общего предка (lca) из двух слов, потому что я хочу сравнить сходство моей профессии на основе их семантических отношений.

У меня есть графиккак это:

CREATE (profession_1:Profession {title: 'Goldsmith'})
CREATE (profession_2:Profession {title: 'Silversmith'})
CREATE (profession_3:Profession {title: 'Blacksmith'})
CREATE (profession_4:Profession {title: 'Carpenter'})

CREATE (task_1:pa {id:'1', description: 'forge gold to necklace and ring'})
CREATE (task_2:pa {id:'2', description: 'mould silver to ring and finger ring'})
CREATE (task_3:pa {id:'3', description: 'forge iron to chain'})
CREATE (task_4:pa {id:'4', description: 'saw wood to board'})
CREATE (task_5:pa {id:'5', description: 'check gold'})
CREATE (task_6:pa {id:'6', description: 'check silver'})
CREATE (task_7:pa {id:'7', description: 'make furniture from wood'})

CREATE (GNROOT:Lexunit {lexunit_id: '1', orth_form: 'GNROOT', depth: 0})
CREATE (forge:Lexunit {lexunit_id: '2', orth_form: 'forge', depth: 3})
CREATE (mould:Lexunit {lexunit_id: '3', orth_form: 'mould', depth: 3})
CREATE (saw:Lexunit {lexunit_id: '4', orth_form: 'saw', depth: 3})
CREATE (gold:Lexunit {lexunit_id: '5', orth_form: 'gold', depth: 4})
CREATE (silver:Lexunit {lexunit_id: '6', orth_form: 'silver', depth: 4})
CREATE (iron:Lexunit {lexunit_id: '7', orth_form: 'iron', depth: 4})
CREATE (wood:Lexunit {lexunit_id: '8', orth_form: 'wood', depth: 2})
CREATE (necklace:Lexunit {lexunit_id: '9', orth_form: 'necklace', depth: 2})
CREATE (ring:Lexunit {lexunit_id: '10', orth_form: 'ring', depth: 2})
CREATE (chain:Lexunit {lexunit_id: '11', orth_form: 'chain', depth: 2})
CREATE (board:Lexunit {lexunit_id: '12', orth_form: 'board', depth: 2})
CREATE (cast:Lexunit {lexunit_id: '13', orth_form: 'cast', depth: 2})
CREATE (cut:Lexunit {lexunit_id: '14', orth_form: 'cut', depth: 2})
CREATE (make:Lexunit {lexunit_id: '15', orth_form: 'make', depth: 1})
CREATE (precious_metal:Lexunit {lexunit_id: '16', orth_form: 'precious metal', depth: 3})
CREATE (heavy_metal:Lexunit {lexunit_id: '17', orth_form: 'heavy metal', depth: 3})
CREATE (metal:Lexunit {lexunit_id: '18', orth_form: 'metal', depth: 2})
CREATE (ressource:Lexunit {lexunit_id: '19', orth_form: 'ressource', depth: 1})
CREATE (jewellery:Lexunit {lexunit_id: '20', orth_form: 'jewellery', depth: 1})
CREATE (string:Lexunit {lexunit_id: '21', orth_form: 'string', depth: 1})
CREATE (part_of_building:Lexunit {lexunit_id: '22', orth_form: 'part of building', depth: 1})
CREATE (finger_ring:Lexunit {lexunit_id: '23', orth_form: 'finger ring', depth: 3})
CREATE (check:Lexunit {lexunit_id: '24', orth_form: 'check', depth: 1})
CREATE (furniture:Lexunit {lexunit_id: '25', orth_form: 'furniture', depth: 1})

MERGE (profession_1)-[:HAS_PA]->(task_1)
MERGE (profession_2)-[:HAS_PA]->(task_2)
MERGE (profession_3)-[:HAS_PA]->(task_3)
MERGE (profession_4)-[:HAS_PA]->(task_4)
MERGE (profession_1)-[:HAS_PA]->(task_5)
MERGE (profession_2)-[:HAS_PA]->(task_6)
MERGE (profession_4)-[:HAS_PA]->(task_7)

MERGE (task_1)-[:HAS_ARB]->(forge)
MERGE (task_1)-[:HAS_MAT]->(gold)
MERGE (task_1)-[:HAS_PRO]->(necklace)
MERGE (task_1)-[:HAS_PRO]->(ring)

MERGE (task_2)-[:HAS_ARB]->(mould)
MERGE (task_2)-[:HAS_MAT]->(silver)
MERGE (task_2)-[:HAS_PRO]->(ring)
MERGE (task_2)-[:HAS_PRO]->(finger_ring)

MERGE (task_3)-[:HAS_ARB]->(forge)
MERGE (task_3)-[:HAS_MAT]->(iron)
MERGE (task_3)-[:HAS_PRO]->(chain)

MERGE (task_4)-[:HAS_ARB]->(saw)
MERGE (task_4)-[:HAS_MAT]->(wood)
MERGE (task_4)-[:HAS_PRO]->(board)

MERGE (task_5)-[:HAS_ARB]->(check)
MERGE (task_5)-[:HAS_MAT]->(gold)

MERGE (task_6)-[:HAS_ARB]->(check)
MERGE (task_6)-[:HAS_MAT]->(silver)

MERGE (task_7)-[:HAS_ARB]->(make)
MERGE (task_7)-[:HAS_MAT]->(wood)
MERGE (task_7)-[:HAS_PRO]->(furniture)

MERGE (forge)-[:HAS_HYPERNYM]->(cast)
MERGE (mould)-[:HAS_HYPERNYM]->(cast)
MERGE (saw)-[:HAS_HYPERNYM]->(cut)
MERGE (cast)-[:HAS_HYPERNYM]->(make)
MERGE (cut)-[:HAS_HYPERNYM]->(make)
MERGE (make)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (gold)-[:HAS_HYPERNYM]->(precious_metal)
MERGE (silver)-[:HAS_HYPERNYM]->(precious_metal)
MERGE (iron)-[:HAS_HYPERNYM]->(heavy_metal)
MERGE (precious_metal)-[:HAS_HYPERNYM]->(metal)
MERGE (heavy_metal)-[:HAS_HYPERNYM]->(metal)
MERGE (metal)-[:HAS_HYPERNYM]->(ressource)
MERGE (wood)-[:HAS_HYPERNYM]->(ressource)
MERGE (necklace)-[:HAS_HYPERNYM]->(jewellery)
MERGE (ring)-[:HAS_HYPERNYM]->(jewellery)
MERGE (finger_ring)-[:HAS_HYPERNYM]->(ring)
MERGE (chain)-[:HAS_HYPERNYM]->(string)
MERGE (board)-[:HAS_HYPERNYM]->(part_of_building)
MERGE (jewellery)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (string)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (part_of_building)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (ressource)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (check)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (furniture)-[:HAS_HYPERNYM]->(GNROOT)

простые совпадения, такие как: MATCH p = (n:Lexunit {orth_form: "mould"})-[:HAS_HYPERNYM*]->(x)<-[:HAS_HYPERNYM*]-(m:Lexunit {orth_form: "saw"}) RETURN x.depth должны иметь плохую производительность для моего реального графика, но алгоритмы вроде:

MATCH aspaths = AllShortestPaths( (start:Lexunit{orth_form:'mould'})-[*]-(end:Lexunit{orth_form:'saw'}) )
WHERE ALL (r in relationships(aspaths) WHERE type(r) = 'HAS_HYPERNYM')
RETURN aspaths

имеют возможность, что они ненайти наименьшего общего предка, но только общего родственника, потому что отношение должно быть направлено на предка (начало) - [rel] -> (lca) <- [rel] - (конец) Если это не так (начало) -[rel] - (lca) - [rel] - (конец) иногда проходит путь, по которому дерево снова поднимается. Поэтому я попытался использовать более сложный запрос: </p>

MATCH (start:Lexunit{orth_form:'mould'}), (end:Lexunit{orth_form:'saw'})
CALL algo.shortestPath.stream(start, end, 'distance', {
nodeQuery:'MATCH(n:Lexunit) RETURN id(n) as id',
relationshipQuery:'MATCH(n:Lexunit)-[:HAS_HYPERNYM*]->(x)<-[:HAS_HYPERNYM*]-(m:Lexunit) RETURN id(n) as source, id(m) as target, count(*) as weight',
graph:'cypher'})
YIELD nodeId, cost
RETURN algo.asNode(nodeId).orth_form AS name, cost

... но он показывает только начало и конец узла:

"имя", "стоимость"

"mould", 0.0

"saw", 1.0

Я был бы очень признателен за небольшую помощь здесь.

Профиль из последнего запроса:

введите описание изображения здесь

Спасибо!

...