2016-09-15 14 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にはあまり適していませんか?このことを理解しようと少し苦労している、どんな助けや考えもありがとう! URLノードでの

答えて

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 

私はそれがタグ付けの時にこのアルゴリズムを使用してタグの組み合わせを計算して保存するのが最善だと思います。クエリは次のようなものになります。

+0

すばらしいもの。本当に興味深いアプローチで、グラフの新生児として、このソリューションに助けを借りるのにしばらく時間がかかります。とても有難い! –

0

スタートは、(彼らので、すべてのグループまで同じ一次のことを)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

真、それは、バーチャルサブセットではなく離散した既存のタグセットを計算するだけです...これは楽しい質問です。 –

関連する問題