web-dev-qa-db-ja.com

関係が存在しない場合はノードを返します

私はシェフが持っているかもしれない不足している成分を「見つける」サイファーを使用してクエリを作成しようとしています、私のグラフは次のように設定されています:

(ingredient_value)-[:is_part_of]->(ingredient)

(ingredient)には、name = "dye colors"のキー/値があります。 (ingredient_value)は、value = "red"および "の一部"のキー/値を持つことができます(ingredient, name="dye colors")

(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)

私はこのクエリを使用して、レシピに必要なすべてのingredientsを取得しますが、実際の値は取得しませんが、シェフが持っていないingredientsのみを返したい各レシピが必要とするすべての材料の。私は試した

(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)<-[:has_ingredient*0..0]-chef

しかし、これは何も返しませんでした。

これはcypher/neo4jで達成できるものですか、それともすべての成分を返して自分でソートすることで処理するのが最適ですか?

ボーナス:シェフが持っているすべての値を、レシピが必要とするすべての値に一致させるためにcypherを使用する方法もあります。これまでのところ、chef-[:has_value]->ingredient_value<-[:requires_value]-recipeによって返され、結果を自分で集計するすべての部分一致のみを返しました。

77
Nicholas

2013年1月10日更新:

Neo4jでこれに遭遇しました2.リファレンス:

オプションの関係を使用しないでください。とりわけ、

次のように使用しないでください:

MATCH a-[r?:LOVES]->() WHERE r IS NULL存在しないことを確認するだけです。

代わりに次のようにします:

MATCH a WHERE NOT (a)-[:LOVES]->()

関係が存在しないかどうかを確認するために暗号を使用する:

...
MATCH source-[r?:someType]-target
WHERE r is null
RETURN source

?マークは関係をオプションにします。

OR

Neo4j 2では:

...
OPTIONAL MATCH source-[r:someType]-target
WHERE r is null
RETURN source

これで、存在しない(null)関係を確認できます。

141
Gil Stal

関係のないノードを取得する場合

これは、関係が存在するかどうかを確認するのに適したオプションです

MATCH (player)-[r:played]->()
    WHERE r IS NULL 
    RETURN player

このための複数の条件を確認することもできます。これは、「played」または「notPlayed」関係を持たないすべてのノードを返します。

MATCH (player) 
 WHERE NOT (player)-[:played|notPlayed]->()
 RETURN player

関係を持たないノードを取得するには

MATCH (player) 
WHERE NOT (player)-[r]-()
RETURN player

ノードは、着信/発信の関係がないことを確認します。

14
Satish Shinde

「条件付き除外」セマンティックが必要な場合は、この方法で実現できます。

Neo4j 2.2.1現在、OPTIONAL MATCH句を使用して、unmatched(NULL)ノードを除外できます。

OPTIONAL MATCH句とWITH句の間にWHERE句を使用することも重要です。これにより、最初のWHEREがオプションの一致の条件を定義し、2番目のWHEREはフィルターのように動作します。

PersonCommunicationの2種類のノードがあると仮定します。電話で通信したことはないが、他の方法で通信した可能性があるすべてのPersonを取得したい場合は、次のクエリを作成します。

MATCH (p: Person) 
OPTIONAL MATCH p--(c: Communication) 
WHERE c.way = 'telephone'
WITH p, c 
WHERE c IS NULL 
RETURN p

一致パターンは、すべての人と通信を照合します。ここで、cは、電話以外の通信ではNULLになります。次に、filter(WHERE after WITH)は、他のすべてを残す電話通信を除外します。

参照:

http://neo4j.com/docs/stable/query-optional-match.html#_introduction_http://Java.dzone.com/articles/new-neo4j-optional

7

最後のクエリは次のとおりです。

START chef = node(..)
MATCH (chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
WHERE (ingredient)<-[:has_ingredient]-chef
RETURN ingredient

このパターン:(ingredient)<-[:has_ingredient*0..0]-chef

それが何も返さなかった理由です。 *0..0は、関係の長さがゼロでなければならないことを意味します。つまり、材料とシェフは同じノードでなければならないことを意味します。

2
Andres

私はグレムリンを使用してこのタスクを完了しました。やった

x=[]

g.idx('Chef')[[name:'chef1']].as('chef')
.out('has_ingredient').as('alreadyHas').aggregate(x).back('chef')
.out('has_value').as('values')
.in('requires_value').as('recipes')
.out('requires_ingredient').as('ingredients').except(x).path()

これにより、不足しているすべての成分のパスが返されました。少なくともバージョン1.7では、これを暗号言語で定式化できませんでした。

2
Nicholas

Cypher 2.0を使用してこれを非常に自然に行う方法を示す要点を書きました

http://Gist.neo4j.org/?9171581

重要な点は、利用可能な成分にオプションの一致を使用し、欠落している(ヌル)成分または間違った値の成分のフィルターと比較することです。

この概念は宣言的であり、アルゴリズムを記述する必要はなく、必要なものを書き留めてください。

2
boggle