1 回答

TA貢獻1982條經驗 獲得超2個贊
Py2neo 支持進行 Cypher 查詢,這里有一個很好的 hello-world 教程,介紹如何做到這一點。
因此,我將提供一個帶注釋的 Cypher 查詢,希望對您有用。
但首先,請注意幾點:
您不應該為服務于相同目的的關系提供幾乎無限數量的類型(如“0.2”、“0.5”等),因為當您想要按類型搜索特定關系時,這是非常無益的(這是其中之一你會想做的最常見的事情)并且會導致大量的關系類型。所以我在我的回答中假設利益關系實際上都有類型
TO
。我的查詢使用一個臨時
Temp
節點來存儲查詢的臨時狀態,因為它遍歷隨機路徑中的關系。該Temp
節點將在查詢結束時被刪除。
查詢如下:
// Get the (assumed-unique) starting Node `n`?
MATCH (n:Node)
WHERE n.name = 'Node-1'
// Create (if necessary) the unique `Temp` node, and initialize
// it with the native ID of the starting node and an empty `pathRels` list
MERGE (temp:Temp)
SET temp = {id: ID(n), pathRels: []}
WITH temp
// apoc.periodic.commit() repeatedly executes the query passed to it
// until it returns 0 or NULL.
// The query passed here iteratively extends the list of relationships
// in `temp.pathRels`. In each iteration, if the current `temp.id`
// node has any outgoing `TO` relationships, the query:
// - appends to `temp.pathRels` a randomly-selected relationship, taking
//? ?into account the relationship weights (which MUST sum to 1.0),
// - sets `temp.id` to the ID of the end node of that selected relationship,
// - and returns 1.
// But if the current `temp.id` node has no outgoing `TO` relationships, then
// the query returns 0.
CALL apoc.periodic.commit(
? "
? ? MATCH (a:Node)
? ? WHERE ID(a) = $temp.id
? ? WITH a, [(a)-[rel:TO]->() | rel] AS rels
? ? LIMIT 1 // apoc.periodic.commit requires a LIMIT clause. `LIMIT 1` should be harmless here.
? ? CALL apoc.do.when(
? ? ? SIZE(rels) > 0,
? ? ? '
? ? ? ?WITH temp, a, REDUCE(s={x: rand()}, r IN rels | CASE
? ? ? ? ?WHEN s.x IS NULL THEN s
? ? ? ? ?WHEN s.x < r.weight THEN {x: NULL, pathRel: r}
? ? ? ? ?ELSE {x: s.x - r.weight} END
? ? ? ?).pathRel AS pathRel
? ? ? ?SET temp.id = ID(ENDNODE(pathRel)), temp.pathRels = temp.pathRels + pathRel
? ? ? ?RETURN 1 AS result
? ? ? ',
? ? ? '
? ? ? ?RETURN 0 AS result
? ? ? ',
? ? ? {temp: $temp, a: a, rels: rels}
? ? ) YIELD value
? ? RETURN value.result
? ",
? {temp: temp}
) YIELD batchErrors
// Use the `temp.pathRels` list to generate the `weightedRandomPath`
// (or you could just return `pathRels` as-is).
// Then delete the `Temp` node, since it is no longer needed.
// Finally, return `weightedRandomPath`, and also the `batchErrors` returned by
// apoc.periodic.commit() (in case it had any errors).?
WITH temp, apoc.path.create(STARTNODE(temp.pathRels[0]), temp.pathRels) AS weightedRandomPath, batchErrors
DELETE temp
RETURN weightedRandomPath, batchErrors
添加回答
舉報