यदि संबंध मौजूद नहीं है, तो नोड लौटाएं


88

मैं साइबर का उपयोग करके एक क्वेरी बनाने की कोशिश कर रहा हूं जो कि एक शेफ की हो सकती है, जो लापता सामग्री को "ढूंढें", मेरा ग्राफ़ ऐसा सेट किया गया है:

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

(ingredient)नाम की एक कुंजी / मान होगा = "डाई रंग"। (ingredient_value)मूल्य की एक कुंजी / मूल्य हो सकता है = "लाल" और "का हिस्सा है" (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

लेकिन यह कुछ भी नहीं लौटाया।

क्या यह कुछ ऐसा है जिसे साइबर / neo4j द्वारा पूरा किया जा सकता है या क्या यह कुछ ऐसा है जो सभी सामग्रियों को वापस करके और उनके माध्यम से खुद को हल करने के लिए सबसे अच्छा है?

बोनस: इसके अलावा साइबरफेयर का उपयोग करने के लिए सभी मूल्यों से मेल खाने के लिए एक तरीका है जो एक शेफ के पास सभी मूल्यों के लिए है जो एक नुस्खा की आवश्यकता होती है। अब तक मैं केवल उन सभी आंशिक मैचों को लौटाता chef-[:has_value]->ingredient_value<-[:requires_value]-recipeहूं, जो खुद ही वापस आ जाते हैं और परिणामों को एकत्र करते हैं।


V3 से संबंधित जानकारी के लिए यहाँ देखें: stackoverflow.com/questions/25673223/…
Maciej

भविष्य के उपयोगकर्ताओं के लिए; अधिक जानकारी के लिए existsएक WHEREक्लॉज (इसे नकारात्मक भी कह सकते हैं ), neo4j.com/developer/subqueries/#existential-subqueries में उपयोग कर सकते हैं ।
ozanmuyes

जवाबों:


157

अद्यतन 01/10/2013:

Neo4j 2.0 संदर्भ में इस पर आया :

वैकल्पिक संबंधों का उपयोग न करने का प्रयास करें। सबसे ऊपर,

उन्हें इस तरह का उपयोग न करें:

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

? निशान रिश्ते को वैकल्पिक बनाता है।

या

Neo4j 2 में करें:

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

अब आप गैर-मौजूदा (अशक्त) संबंध की जांच कर सकते हैं।


3
Neo4j 2.0 में, वैकल्पिक संबंधों से मेल खाने के लिए OPTIONAL MATCH का उपयोग करें, अर्थात पहला उदाहरण OPTIONAL MATCH (स्रोत) - [r: someType] - (लक्ष्य) RETURN स्रोत, r
boggle

मैं कोशिश कर रहा हूं कि जहां नहीं है वहां एक लेबल नोड है, यह काम नहीं करता है। जैसे: MATCH WHERE NOT (a) - [: LOVES] -> (अजनबी), इस 'Stranger' में एक नोड लेबल है। मैं neo4j संस्करण 2.1.2 का उपयोग कर रहा हूं
कृष्णा शेट्टी

1
कोई बात नहीं, मैं समझता हूं कि आप इस उत्तर तक पहुंचने के लिए प्रगति क्यों दिखाना चाहते हैं: MATCH WHERE NOT (a) - [: LOVES] -> ()
NumenorForLife

4
MATCH a...उदाहरण अब होना चाहिएMATCH (a) WHERE NOT (a)-[:LOVES]->()
लियाम

1
@ गिल-स्टाल क्यों मैं इस तरह इस क्वेरी के साथ नोड नाम का उपयोग नहीं कर सकता। एक कहां नहीं है (ए) - [: प्यार करता है] -> (बी: SomeLabel)। अगर मैं नोड नाम का उपयोग नहीं करता हूं तो यह काम करता है।
Iit2011081

15

किसी भी संबंध के साथ नोड्स लाने के लिए

यह जाँचने का अच्छा विकल्प है कि रिश्ता मौजूद है या नहीं

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

आप इसके लिए कई शर्तें भी देख सकते हैं कि यह सभी नोड्स लौटा देगा, जिनमें "प्ले" या "नोट नहीं" संबंध नहीं है।

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

नोड्स लाने के लिए जो किसी भी realtionship नहीं है

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

यह नोड की आवक / जावक संबंध नहीं होने की जाँच करेगा।


4
MATCH (player) WHERE NOT (player)-[r]-() RETURN playerचर आर को परिभाषित त्रुटि नहीं देता है । मैं आर को कैसे परिभाषित कर सकता हूं?
चतुरा विजीवेरा

इसे ठीक करने के लिए, या तो एक संबंध निर्दिष्ट करें (जैसे (player -[:rel]- ()) या किसी भी संबंध के लिए खाली छोड़ दें(player -[]- ()
आर्कमेयर

MATCH (player) WHERE NOT (player)-[]-() RETURN player- यह ठीक काम करता है
प्रशान्त तेरा

आपकी पहली क्वेरी वास्तव में गलत है। MATCH पैटर्न हमेशा केवल मौजूदा रिश्ते देता है, उनमें से कोई भी NULL नहीं है। तो आपकी WHERE लाइन के पास फ़िल्टर करने के लिए कुछ भी नहीं है।
क्रिस्टी एस

@CristiS। मुझे बताने के लिए धन्यवाद। मैंने क्वेरी को काम करना चाहिए
सतीश शिंदे

8

यदि आपको "सशर्त बहिष्कृत" शब्दार्थ की आवश्यकता है, तो आप इसे इस तरह से प्राप्त कर सकते हैं।

Neo4j 2.2.1 के रूप में, आप OPTIONAL MATCHखंड का उपयोग कर सकते हैं और बेजोड़ ( NULL) नोड्स को फ़िल्टर कर सकते हैं ।

क्लॉस और क्लॉज़ के WITHबीच क्लॉज़ का उपयोग करना भी महत्वपूर्ण है , ताकि पहला वैकल्पिक मैच के लिए एक शर्त को परिभाषित करे और दूसरा एक फिल्टर की तरह व्यवहार करे।OPTIONAL MATCHWHEREWHEREWHERE

मान लें कि हमारे पास 2 प्रकार के नोड हैं: Personऔर Communication। यदि मैं उन सभी व्यक्तियों को प्राप्त करना चाहता हूं, जिन्होंने कभी भी टेलीफोन द्वारा संचार नहीं किया है, लेकिन अन्य तरीकों से संचार कर सकते हैं, तो मैं यह प्रश्न बनाऊंगा:

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

मेल खाने वाला पैटर्न उनके संचार के साथ सभी व्यक्तियों जहां से मेल खाएगी cहो जाएगा NULLगैर टेलीफोन संचार के लिए। फिर फ़िल्टर ( WHEREबाद में WITH) अन्य सभी को छोड़कर टेलीफोन संचार को फ़िल्टर करेगा।

संदर्भ:

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


2

मैंने एक जिस्ट लिखा है जिसमें दिखाया गया है कि यह साइफ्रे 2.0 का उपयोग करके स्वाभाविक रूप से किया जा सकता है

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

मुख्य बिंदु उपलब्ध सामग्री के लिए वैकल्पिक मैच का उपयोग करना है और फिर लापता (अशक्त) अवयवों या अवयवों के लिए फ़िल्टर की तुलना गलत मान के साथ करना है।

ध्यान दें कि धारणा घोषणात्मक है और एक एल्गोरिथ्म का वर्णन करने की आवश्यकता नहीं है, आप बस वही लिखते हैं जिसकी आपको आवश्यकता है।


2

मैंने ग्रेमलिन का उपयोग करके इस कार्य को पूरा किया। मैंने किया

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

अंतिम प्रश्न यह होना चाहिए:

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इसका मतलब है कि रिश्तों की लंबाई शून्य होनी चाहिए, जिसका मतलब है कि घटक और रसोइया एक ही नोड होना चाहिए, जो वे नहीं हैं।


हां, लेकिन यह वांछित घटक को वापस नहीं करता है। यह वही देता है जो रसोइया के पास पहले से ही आम है, मैं इसका अंतर जानना चाहता हूं।
निकोलस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.