Próbuję utworzyć zapytanie za pomocą szyfru, które pozwoli „znaleźć” brakujące składniki, które może mieć szef kuchni. Mój wykres wygląda następująco:
(ingredient_value)-[:is_part_of]->(ingredient)
(ingredient)
miałby klucz / wartość nazwa = "kolory barwnika". (ingredient_value)
może mieć klucz / wartość wartość = „czerwony” i „jest częścią” (ingredient, name="dye colors")
.
(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
Używam tego zapytania, aby uzyskać wszystkie ingredients
wymagane przez przepis wartości, ale nie ich rzeczywiste wartości, ale chciałbym zwrócić tylko to ingredients
, czego szef kuchni nie ma, zamiast wszystkich składników wymaganych w każdym przepisie. próbowałem
(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)<-[:has_ingredient*0..0]-chef
ale to nic nie zwróciło.
Czy jest to coś, co można osiągnąć za pomocą cypher / neo4j, czy jest to coś, z czym najlepiej sobie poradzić, zwracając wszystkie składniki i samodzielnie je przeglądając?
Bonus: istnieje również sposób, aby użyć szyfrowania, aby dopasować wszystkie wartości, które ma szef kuchni, do wszystkich wartości, których wymaga przepis. Do tej pory zwracałem tylko wszystkie częściowe dopasowania, które są zwracane przez a, chef-[:has_value]->ingredient_value<-[:requires_value]-recipe
i sam agregowałem wyniki.
exists
wWHERE
klauzuli (również ją zanegować), neo4j.com/developer/subqueries/#existential-subqueries, aby uzyskać więcej informacji.Odpowiedzi:
Aktualizacja 10.01.2013:
Spotkałem się z tym w referencji Neo4j 2.0 :
Staraj się nie używać opcjonalnych relacji. Ponad wszystko,
nie używaj ich w ten sposób:
MATCH a-[r?:LOVES]->() WHERE r IS NULL
gdzie po prostu upewniasz się, że nie istnieją.Zamiast tego zrób to tak:
Używanie cyphera do sprawdzania, czy związek nie istnieje:
The? znak sprawia, że relacja jest opcjonalna.
LUB
W neo4j 2 zrób:
Teraz możesz sprawdzić nieistniejącą (zerową) relację.
źródło
MATCH a...
Przykład powinien być terazMATCH (a) WHERE NOT (a)-[:LOVES]->()
Do pobierania węzłów bez relacji
Jest to dobra opcja, aby sprawdzić, czy związek istnieje, czy nie
Możesz również sprawdzić wiele warunków dla tego. Zwróci wszystkie węzły, które nie „grały” lub „nie odtwarzały” relacji.
Aby pobrać węzły, które nie mają żadnych powiązań
Sprawdza, czy węzeł nie ma żadnych relacji przychodzących / wychodzących.
źródło
MATCH (player) WHERE NOT (player)-[r]-() RETURN player
daje Zmienna r niezdefiniowany błąd. Jak mogę zdefiniować r?(player -[:rel]- ()
) lub pozostaw puste dla dowolnej relacji(player -[]- ()
MATCH (player) WHERE NOT (player)-[]-() RETURN player
- Działa dobrzeJeśli potrzebujesz semantyki „warunkowe wykluczenie”, możesz to osiągnąć w ten sposób.
Począwszy od neo4j 2.2.1, możesz używać
OPTIONAL MATCH
klauzuli i odfiltrowywaćNULL
węzły unmatched ( ).Ważne jest również użycie
WITH
klauzuli między klauzulamiOPTIONAL MATCH
iWHERE
, tak aby pierwszaWHERE
definiowała warunek opcjonalnego dopasowania, a drugaWHERE
zachowywała się jak filtr.Zakładając, że mamy 2 typy węzłów:
Person
iCommunication
. Jeśli chcę uzyskać wszystkie Osoby, które nigdy nie rozmawiały przez telefon, ale mogły porozumiewać się w inny sposób, zadałbym następujące pytanie:Wzorzec dopasowania będzie pasował do wszystkich osób z ich komunikacją, gdzie
c
będzieNULL
dotyczyła komunikacji nietelefonicznej. Następnie filtr (WHERE
poWITH
) odfiltruje komunikację telefoniczną, pozostawiając wszystkie inne.Bibliografia:
http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3 http://java.dzone.com/articles/new-neo4j-optional
źródło
Napisałem streszczenie pokazujące, jak można to zrobić całkiem naturalnie za pomocą Cypher 2.0
http://gist.neo4j.org/?9171581
Kluczową kwestią jest użycie opcjonalnego dopasowania do dostępnych składników, a następnie porównanie z filtrem pod kątem brakujących (zerowych) składników lub składników o niewłaściwej wartości.
Zwróć uwagę, że pojęcie jest deklaratywne i nie musi opisywać algorytmu, po prostu zapisz, czego potrzebujesz.
źródło
Wykonałem to zadanie za pomocą gremlin. Zrobiłem
To zwróciło ścieżki wszystkich brakujących składników. Nie byłem w stanie sformułować tego w szyfrowanym języku, przynajmniej w wersji 1.7.
źródło
Ostatnie zapytanie powinno brzmieć:
Ten wzór:
(ingredient)<-[:has_ingredient*0..0]-chef
Jest powodem, dla którego nic nie zwróciło.
*0..0
oznacza, że długość relacji musi wynosić zero, co oznacza, że składnik i szef kuchni muszą być tym samym węzłem, którym nie są.źródło