私はシェフが持っているかもしれない不足している成分を「見つける」サイファーを使用してクエリを作成しようとしています、私のグラフは次のように設定されています:
(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
によって返され、結果を自分で集計するすべての部分一致のみを返しました。
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)関係を確認できます。
関係のないノードを取得する場合
これは、関係が存在するかどうかを確認するのに適したオプションです
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
ノードは、着信/発信の関係がないことを確認します。
「条件付き除外」セマンティックが必要な場合は、この方法で実現できます。
Neo4j 2.2.1現在、OPTIONAL MATCH
句を使用して、unmatched(NULL
)ノードを除外できます。
OPTIONAL MATCH
句とWITH
句の間にWHERE
句を使用することも重要です。これにより、最初のWHERE
がオプションの一致の条件を定義し、2番目のWHERE
はフィルターのように動作します。
Person
とCommunication
の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
最後のクエリは次のとおりです。
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
は、関係の長さがゼロでなければならないことを意味します。つまり、材料とシェフは同じノードでなければならないことを意味します。
私はグレムリンを使用してこのタスクを完了しました。やった
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では、これを暗号言語で定式化できませんでした。
Cypher 2.0を使用してこれを非常に自然に行う方法を示す要点を書きました
http://Gist.neo4j.org/?9171581
重要な点は、利用可能な成分にオプションの一致を使用し、欠落している(ヌル)成分または間違った値の成分のフィルターと比較することです。
この概念は宣言的であり、アルゴリズムを記述する必要はなく、必要なものを書き留めてください。