2016-09-15 6 views
4

URL을 설명하는 데 사용되는 태그와 태그로 구성된 그래프 데이터베이스를 상상해보십시오. 이를 통해 우리는 가장 자주 사용되는 태그 집합을 찾고 각 식별 된 집합에 속하는 URL을 결정하고자합니다.가장 자주 사용되는 별개의 용어 집합 찾기

내가이 cypher에서 같은 문제를 단순화하는 데이터 세트 만들려고했습니다 참조 (neo4j console example here)로이 사용

CREATE (tech:Tag { name: "tech" }), (comp:Tag { name: "computers" }), (programming:Tag { name: "programming" }), (cat:Tag { name: "cats" }), (mice:Tag { name: "mice" }), (u1:Url { name: "http://u1.com" })-[:IS_ABOUT]->(tech), (u1)-[:IS_ABOUT]->(comp), (u1)-[:IS_ABOUT]->(mice), (u2:Url { name: "http://u2.com" })-[:IS_ABOUT]->(mice), (u2)-[:IS_ABOUT]->(cat), (u3:Url { name: "http://u3.com" })-[:IS_ABOUT]->(tech), (u3)-[:IS_ABOUT]->(programming), (u4:Url { name: "http://u4.com" })-[:IS_ABOUT]->(tech), (u4)-[:IS_ABOUT]->(mice), (u4)-[:IS_ABOUT]->(acc:Tag { name: "accessories" }) 

을, 우리는 그것을보고 시각적으로 가장 일반적으로 사용되는 것을 확인할 수 있습니다 태그는 techmice (이 쿼리는 간단합니다) 모두 3 개의 URL을 참조합니다. 가장 일반적으로 사용되는 태그 쌍은 [tech, mice] (이 예에서)은 2 개의 URL (u4 및 u1)로 공유되는 유일한 쌍입니다. 이 태그 쌍은 일치하는 URL의 하위 집합이므로 둘 중 하나에 대한 전체 집합이 아니라는 점에 유의해야합니다. 모든 URL에서 공유하는 3 개의 태그 조합은 없습니다.

cypher 검색어를 사용하여 가장 자주 사용되는 태그 조합 (쌍 또는 N 크기 그룹)을 식별하려면 어떻게해야합니까? 분석을 쉽게하는이 데이터를 구조화하는 더 좋은 방법이 있을까요? 아니면이 문제는 그래프 DB에 적합하지 않습니까? 이 것을 파악하려고 애쓰는 데 조금 어려움을 겪어 왔습니다. 어떤 도움이나 생각이라도 고맙게 여길 것입니다!

답변

1

조합에 관한 문제인 것처럼 보입니다.

// The tags for each URL, sorted by ID 
MATCH (U:Url)-[:IS_ABOUT]->(T:Tag) 
WITH U, T ORDER BY id(T) 
WITH U, 
    collect(distinct T) as TAGS 

// Calc the number of combinations of tags for a node, 
// independent of the order of tags 
// Since the construction of the power in the cyper is not available, 
// use the logarithm and exponent 
// 
WITH U, TAGS, 
    toInt(floor(exp(log(2) * size(TAGS)))) as numberOfCombinations 

// Iterate through all combinations 
UNWIND RANGE(0, numberOfCombinations) as combinationIndex 
WITH U, TAGS, combinationIndex 

// And check for each tag its presence in combination 
// Bitwise operations are missing in the cypher, 
// therefore, we use APOC 
// https://neo4j-contrib.github.io/neo4j-apoc-procedures/#_bitwise_operations 
// 
UNWIND RANGE(0, size(TAGS)-1) as tagIndex 
WITH U, TAGS, combinationIndex, tagIndex, 
    toInt(ceil(exp(log(2) * tagIndex))) as pw2 
    call apoc.bitwise.op(combinationIndex, "&", pw2) YIELD value 
WITH U, TAGS, combinationIndex, tagIndex, 
    value WHERE value > 0 

// Get all combinations of tags for URL 
WITH U, TAGS, combinationIndex, 
    collect(TAGS[tagIndex]) as combination 

// Return all the possible combinations of tags, sorted by frequency of use 
RETURN combination, count(combination) as freq, collect(U) as urls 
     ORDER BY freq DESC 

태그 지정시이 알고리즘을 사용하여 태그 조합을 계산하고 저장하는 것이 가장 좋습니다. 당신이 용어의 특정 크기의 쌍에만 관심이 있다면

MATCH (Comb:TagsCombination)<-[:IS_ABOUT]-(U:Url) 
WITH Comb, collect(U) as urls, count(U) as freq 
MATCH (Comb)-[:CONTAIN]->(T:Tag) 
RETURN Comb, collect(T) as Tags, urls, freq ORDER BY freq DESC 
+0

좋은 물건. 정말 흥미로운 접근 방법이며, 그래프 초보자 인 경우 도움없이이 솔루션에 도달하는 데 다소 시간이 걸릴 것입니다. 매우 감사! –

0

URL 노드에서 시작하여 tag.name 개체의 튜플을 만듭니다 (먼저 순서를 지정하여 모두 동일하게 그룹화합니다). 존재하는 모든 태그 조합을 제공합니다. 그런 다음 필터를 사용하여 각 가능한 태그 집합에 대해 얼마나 많은 URL 일치를 찾습니다.

MATCH (u:url) 
WITH u 
MATCH (u) - [:IS_ABOUT] -> (t:tag) 
WITH u, t 
ORDER BY t.name 
WITH u, [x IN COLLECT(t)|x.name] AS tags 
WITH DISTINCT tags 
MATCH (u) 
WHERE ALL(tag IN tags WHERE (u) - [:IS_ABOUT] -> (tag)) 
RETURN tags, count(u) 
+0

또한, 크기에 따라'필터링 tags' 수 있습니다 그리고 쿼리는 다음과 같이 될 것입니다. 'WITH DISTINCT tags' 라인 다음에'WHERE size (tags) = 2'라고 쓰십시오. –

+0

감사합니다. @ tore-eschliman은 좋은 통찰력을 제공했지만, 핵심 문제는 태그 하위 집합을 고려하지 않았다는 것입니다. 즉 'A'에 '1,2,3'이라는 태그가 지정되고 'B'에 '2,3,4'태그가 지정되면 '2,3'이 가장 일반적인 쌍으로 식별되지 않습니다. 아마도 이것은 더 이상 생각했던 것을 분석하기위한 출발점으로 사용될 수 있습니다. 이 예제를 더 잘 설명하기 위해 업데이트했습니다. –

+0

사실, 그것은 가상 서브셋이 아닌 개별 태그 세트를 계산할 것입니다 ... 이것은 재미있는 질문입니다. –

관련 문제