3

特定の関係 (特定のプロパティとの関係) を持たないノードを取得したいと考えています。

グラフには、ファイル (f) の特定の行 (line_nr) で発生するエンティティ ノード (n) が含まれます。

現在のクエリは次のとおりです。

start n=node:entities("text:*")
MATCH p=(n)-[left:OCCURS]->(f) 
    , p4=(f)<-[right4?:OCCURS]-(n4) 
    , p7=(f)<-[right7?:OCCURS]-(n7)
WHERE  (  (  
   ( n4.text? =~ "nonreachablenodestextregex" AND (p4 = null OR left.line_nr < right4.line_nr - 0 OR left.line_nr > right4.line_nr + 0 OR ID(left) = ID(right4)  )  )  )  
   AND  (  
   ( n7.text? =~ "othernonreachablenodestextregex" AND (p7 = null OR left.line_nr < right7.line_nr - 0 OR left.line_nr > right7.line_nr + 0 OR ID(left) = ID(right7)  )  )  )  )  
WITH n, left, f, count(*) as group_by_cause 
RETURN ID(left) as occ_id, 
       n.text as ent_text, 
       substring(f.text, ABS(left.file_offset-1), 2 + LENGTH(n.text) ) as occ_text, 
       f.path as file_path, 
       left.line_nr as occ_line_nr, 
       ID(f) as file_id

MATCH 句の新しいパスの代わりに、次のようにすることも可能だと思いました。

NOT ( (f)<-[right4:OCCURS]-(n4) ) 

しかし、パスの存在を排除したくはありませんが、特定のパスです。

別の解決策として、追加の開始ノードを含めて (到達できないノードにインデックスがあるため)、WHERE 句のテキスト比較を削除することを考えました。ただし、neo4j にワイルドカードに一致するノードがない場合、これは何も返しません。

start n=node:entities("text:*")
    , n4=node:entities("text:nonreachablenodestextwildcard")
    , n7=node:entities("text:othernonreachablenodestextwildcard")
MATCH p=(n)-[left:OCCURS]->(f) 
    , p4=(f)<-[right4?:OCCURS]-(n4) 
    , p7=(f)<-[right7?:OCCURS]-(n7)
WHERE  (  (  
   ( (p4 = null 
      OR left.line_nr < right4.line_nr - 0 
      OR left.line_nr > right4.line_nr + 0 
      OR ID(left) = ID(right4)  )  )  )  
   AND  (  
   ( (p7 = null 
      OR left.line_nr < right7.line_nr - 0 
      OR left.line_nr > right7.line_nr + 0 
      OR ID(left) = ID(right7)  )  ) 
)  )  

古い更新: 回答で述べたように、述語関数を使用して内部クエリを作成できました。したがって、クエリを次のように更新しました。

start n=node:entities("text:*") 
MATCH p=(n)-[left:OCCURS]->(f) 
WHERE  (  (  
    (NONE(path in (f)<-[:OCCURS]-(n4) 
         WHERE  
           (LAST(nodes(path))).text =~ "nonreachablenodestextRegex"  
           AND FIRST(r4 in rels(p)).line_nr <= left.line_nr  
           AND FIRST(r4 in rels(p)).line_nr >= left.line_nr 
    )
    ) )  
    AND  (  
   (NONE(path in (f)<-[:OCCURS]-(n7) 
         WHERE  
           (LAST(nodes(path))).text =~ "othernonreachablenodestextRegex"  
           AND FIRST(r7 in rels(p)).line_nr <= left.line_nr   
           AND FIRST(r7 in rels(p)).line_nr >= left.line_nr 
    )
    ) ) 
    )
WITH n, left, f, count(*) as group_by_cause 
RETURN ....

これは私に与えますjava.lang.OutOfMemoryException

java.lang.OutOfMemoryError: Java heap space
at java.util.regex.Pattern.compile(Pattern.java:1432)
at java.util.regex.Pattern.<init>(Pattern.java:1133)
at java.util.regex.Pattern.compile(Pattern.java:823)
at scala.util.matching.Regex.<init>(Regex.scala:38)
at scala.collection.immutable.StringLike$class.r(StringLike.scala:226)
at scala.collection.immutable.StringOps.r(StringOps.scala:31)
at org.neo4j.cypher.internal.parser.v1_9.Base.ignoreCase(Base.scala:31)
at org.neo4j.cypher.internal.parser.v1_9.Base.ignoreCases(Base.scala:49)
at org.neo4j.cypher.internal.parser.v1_9.Base$$anonfun$ignoreCases$1.apply(Base.scala:49)
at org.neo4j.cypher.internal.parser.v1_9.Base$$anonfun$ignoreCases$1.apply(Base.scala:49)
at scala.util.parsing.combinator.Parsers$Parser.p$3(Parsers.scala:209)
at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$1.apply(Parsers.scala:210)
at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$1.apply(Parsers.scala:210)
at scala.util.parsing.combinator.Parsers$Failure.append(Parsers.scala:163)
at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:210)
at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:210)
at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:183)
at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$1.apply(Parsers.scala:210)
at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$1.apply(Parsers.scala:210)
at scala.util.parsing.combinator.Parsers$Failure.append(Parsers.scala:163)

(最後の 6 行はさらに数回繰り返されます)

解決策 前回のアップデートには、おそらくどこかに構文エラーが含まれている可能性があり、次のようにわずかに異なる修正が行われました。

start n=node:entities("text:*") 
MATCH p=(n)-[left:OCCURS]->(f) 
WHERE  (    
(NONE ( path in (f)<-[:OCCURS]-() 
    WHERE  
      ANY(n4 in nodes(path) 
        WHERE ID(n4) <> ID(n) 
          AND n4.type = 'ENTITY' 
          AND n4.text =~ "a regex expr" 
        ) 
      AND ALL(r4 in rels(path)  
        WHERE r4.line_nr <= left.line_nr + 0 
          AND r4.line_nr >= left.line_nr - 0 
        ) 
     )
  ) )
AND  
 NONE ( ......  )  
WITH n, left, f, count(*) as group_by_cause 
RETURN ...

ただし遅いです。小さなグラフの秒単位 (>10): 合計で 4 つのエンティティ ノードと 6 つの :OCCURS 関係、すべて 1 つの宛先 f ノードへ、line_nr は 0 から 3 の間。

パフォーマンスの更新 以下は約 2 倍高速です。

start n=node:entities("text:*") 
MATCH p=(n)-[left:OCCURS]->(f) 
, p4=(f)<-[right4?:OCCURS]-(n4) 
, p7=(f)<-[right7?:OCCURS]-(n7) 
WHERE  
 ( n4.text? =~ "regex1" 
  AND (p4 = null 
       OR left.line_nr < right4.line_nr - 0 
       OR left.line_nr > right4.line_nr + 0 
       OR ID(left) = ID(right4)  
       )
 ) 
 AND  
( n7.text? =~ "regex2" 
  AND (p7 = null .....)
)
WITH n, left, f, count(*) as group_by_cause 
RETURN ....
4

1 に答える 1

0

オプションの関係の代わりに、あなたが指摘したように WHERE でパターン述語を使用する必要があると思います。ALL, NONE, ANY, SINGLEパターン式は実際にはパスのコレクションを返すため、( )のようなコレクション述語を実行できます。

WHERE NONE(path in (f)<-[:OCCURS]-(n4) WHERE 
           ALL(r in rels(p) : r.line_nr = 42 ))

参照: http://docs.neo4j.org/chunked/milestone/query-function.html#_predicates

于 2013-03-26T14:25:42.240 に答える