[英]How can I create relationships in neo4j/Cypher from a csv that depend on the type of nodes?
[英]How can I use neo4j cypher query to create a histogram of nodes bucketed by number of relationships?
我有一大堆節點與下面的密碼相匹配:
(:Word)<-[:Searched]-(:Session)
我想在搜索關系的每個頻率上制作一個Word節點數的直方圖。
我想制作這種圖表:
Searches Words
0 100
1-5 200
6-10 150
11-15 50
16-20 25
我剛剛開始使用neo4j,我不知道如何處理這個問題,或者即使有一種方法可以在cypher中指定它。 我最接近的是計算關系並獲得平均值。
MATCH (n:Word)
RETURN
DISTINCT labels(n),
count(*) AS NumofNodes,
avg(size((n)<-[:Searched]-())) AS AvgNumOfRelationships,
min(size((n)<-[:Searched]-())) AS MinNumOfRelationships,
max(size((n)<-[:Searched]-())) AS MaxNumOfRelationships
這是基於一個例子: https : //neo4j.com/developer/kb/how-do-i-produce-an-inventory-of-statistics-on-nodes-relationships-properties/
我也看到使用模數運算符進行分組以獲取存儲桶,但我不確定如何使用它來引用計數: Neo4j cypher時間間隔直方圖查詢時間樹
有沒有“最好”的方法來做到這一點?
以下應該有效:
WITH 5 AS gSize
MATCH (w:Word)
OPTIONAL MATCH (w)<-[s:Searched]-()
WITH gSize, w, TOINT((COUNT(s) + (gSize-1))/gSize * gSize) AS m
RETURN
CASE m WHEN 0 THEN '0' ELSE (m-gSize+1)+'-'+m END AS range,
COUNT(*) AS ct
ORDER BY range;
使用@GaborSzarnyas提供的示例數據,輸出為:
+-------------+
| range | ct |
+-------------+
| "0" | 1 |
| "1-5" | 1 |
| "6-10" | 1 |
+-------------+
我能夠找出一個我認為能得到我想要的數據的查詢:
MATCH (n:Word)
WITH n, 5 AS bucketsize
WITH (FLOOR(SIZE( (n)<-[:Searched]-() ) / bucketsize) * bucketsize) AS numRels
RETURN numRels, COUNT(*)
ORDER BY numRels ASC
它沒有得到我想擁有的零行,但似乎它起作用。 希望其他人有更好的解決方案。
我創建了一個簡單的三個單詞示例數據集: w1
沒有搜索, w2
有3次搜索, w3
有6次。
CREATE (w1:Word {w: '1'})
WITH count(*) AS dummy
CREATE (w2:Word {w: '2'}) WITH w2
UNWIND range(1, 3) AS i
CREATE (w2)<-[:Searched]-(:Session)
WITH count(*) AS dummy
CREATE (w3:Word {w: '3'}) WITH w3
UNWIND range(1, 6) AS i
CREATE (w3)<-[:Searched]-(:Session)
我會這樣做:首先,讓我們創建一個列表,其中包含每個桶的上限:
RETURN [i IN range(0, 4) | i*5] AS upperLimits
╒══════════════╕
│"upperLimits" │
╞══════════════╡
│[0,5,10,15,20]│
└──────────────┘
其次,將此與列表推導一起使用,從列表中選擇具有足夠大上限的元素。 第一個是我們的存儲桶,因此我們使用[0]
列表索引器選擇它。 其余的只是計算下限和排序行:
WITH [i IN range(0, 4) | i*5] AS upperLimits
MATCH (n:Word)
WITH upperLimits, ID(n) AS n, size((n)<-[:Searched]-()) AS numOfRelationships
WITH
[upperLimit IN upperLimits WHERE numOfRelationships <= upperLimit][0] AS upperLimit,
count(n) AS count
RETURN
upperLimit - 4 AS lowerLimit,
upperLimit,
count
ORDER BY lowerLimit
該查詢提供以下結果:
╒════════════╤════════════╤═══════╕
│"lowerLimit"│"upperLimit"│"count"│
╞════════════╪════════════╪═══════╡
│-4 │0 │1 │
├────────────┼────────────┼───────┤
│1 │5 │1 │
├────────────┼────────────┼───────┤
│6 │10 │1 │
└────────────┴────────────┴───────┘
潛在改進:
(1)如果numOfRelationships
的值大於最大上限,則上面的查詢將返回空列表的第一個元素,即null
。 為避免這種情況,1)設置足夠大的上限,例如
MATCH (n:Word)
WITH max(size((n)<-[:Searched]-())) AS maxNumberOfRelationShips
WITH [i IN range(-1, maxNumberOfRelationShips/5+1) | {lower: i*5-4, upper: i*5}] AS limits
RETURN *
您可以使用帶有“16或更大”語義的頂級存儲區和coalesce
。
(2) -4
作為下限不是很好,我們可以使用CASE
來擺脫它。
把所有這些放在一起,我們得到這個:
MATCH (n:Word)
WITH max(size((n)<-[:Searched]-())) AS maxNumberOfRelationShips
WITH [i IN range(0, maxNumberOfRelationShips/5+1) | i*5] AS upperLimits
MATCH (n:Word)
WITH upperLimits, ID(n) AS n, size((n)<-[:Searched]-()) AS numOfRelationships
WITH
[upperLimit IN upperLimits WHERE numOfRelationships <= upperLimit][0] AS upperLimit,
count(n) AS count
RETURN
CASE WHEN upperLimit - 4 < 0 THEN 0 ELSE upperLimit - 4 END AS lowerLimit,
upperLimit,
count
ORDER BY lowerLimit
結果如下:
╒════════════╤════════════╤═══════╕
│"lowerLimit"│"upperLimit"│"count"│
╞════════════╪════════════╪═══════╡
│0 │0 │1 │
├────────────┼────────────┼───────┤
│1 │5 │1 │
├────────────┼────────────┼───────┤
│6 │10 │1 │
└────────────┴────────────┴───────┘
我在這種情況下通常做的是我使用neo4j中的設置,如果你將整數除以整數,你會得到一個整數。 這簡化了查詢。 我們為0添加一個特殊情況,它們都適合一行。
WITH [0,1,5,7,9,11] as list
UNWIND list as x
WITH CASE WHEN x = 0 THEN -1 ELSE (x / 5) * 5 END as results
return results
這回來了
-1,0,5,5,5,10
考慮到你想要將1-5組合在一起,這是不理想的,但我認為足夠好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.