मैं एक ग्रेमलिन क्वेरी को एक साथ रखने की कोशिश कर रहा हूं जो एक निश्चित किनारे प्रकार की 1 से n गहराई के लिए परिणाम देता है - .union() के साथ सिले हुए कई प्रश्नों का उपयोग करने के बिना बिना

मेरे पास कुछ परीक्षण डेटा है जो बिक्री कार्यालयों और उनमें काम करने वाले लोगों की संरचना का अनुकरण करता है, जिसमें यह भी शामिल है कि कौन से कार्यालयों का प्रबंधन करता है और कौन से कार्यालय उच्च स्तर के कार्यालयों के अधिकार क्षेत्र में "रोल अप" करते हैं। निम्नलिखित स्क्रीन शॉट (वास्तव में Neo4j से) उस ग्राफ का एक सबसेट दिखाता है जिसे मैं संदर्भित करने जा रहा हूं।

Graph of sample data

ग्राफ निम्नलिखित के साथ बनाया जा सकता है:

g.
addV('Office').as('O_111').property('code','111').
addV('Office').as('O_356').property('code','356').
addV('Office').as('O_279').property('code','279').
addV('Office').as('O_KC5').property('code','KC5').
addE('MERGES_INTO').from('O_356').to('O_111').
addE('MERGES_INTO').from('O_279').to('O_356').
addE('MERGES_INTO').from('O_KC5').to('O_279').
addV('Person').as('Bob').property('name','Bob').
  addE('MANAGES').from('Bob').to('O_111').addE('WORKS_WITH').from('Bob').to('O_111').
addV('Person').as('Michael').property('name','Michael').addE('WORKS_WITH').from('Michael').to('O_111').
addV('Person').as('John').property('name','John').addE('WORKS_WITH').from('John').to('O_111').
addV('Person').as('Rich').property('name','Rich').addE('WORKS_WITH').from('Rich').to('O_111').
addV('Person').as('Matt').property('name','Matt').
  addE('WORKS_WITH').from('Matt').to('O_279').addE('MANAGES').from('Matt').to('O_279').
addV('Person').as('Judy').property('name','Judy').addE('WORKS_WITH').from('Judy').to('O_279').
addV('Person').as('Joe').property('name','Joe'). addE('WORKS_WITH').from('Joe').to('O_279').
addV('Person').as('Ben').property('name','Ben').addE('WORKS_WITH').from('Ben').to('O_279').
addV('Person').as('Ron').property('name','Ron').addE('WORKS_WITH').from('Ron').to('O_KC5').

अगर मैं यह देखना चाहता हूं कि कौन से लोग (नारंगी) एक कार्यालय (गुलाबी) के साथ काम करते हैं जिसे बॉब प्रत्यक्ष या अप्रत्यक्ष रूप से प्रबंधित करता है (क्योंकि, उदाहरण के लिए, कार्यालय KC5, 279, और 356 बॉब के 111 कार्यालय तक रोल करते हैं), तो मैं उपयोग कर सकता हूं .union() और उचित परिणाम प्राप्त करने के लिए निम्न जैसा कुछ:

gremlin> g.V().has('Person','name','Bob').
......1>   out('MANAGES').
......2>   union(
......3>     __.in('WORKS_WITH'),
......4>     __.in('MERGES_INTO').in('WORKS_WITH'),
......5>     __.in('MERGES_INTO').in('MERGES_INTO').in('WORKS_WITH'),
......6>     __.in('MERGES_INTO').in('MERGES_INTO').in('MERGES_INTO').in('WORKS_WITH')
......7>     ).
......8>   values('name').fold()
==>[Bob, Michael, John, Rich, Matt, Judy, Joe, Ben, Ron]

यह सुपर वर्बोज़ और अजीब लगता है। क्या यही मेरी एकमात्र पसंद है? क्या कोई बेहतर तरीका है जो .union() जैसा बेमानी न लगे?

एक Neo4j दुनिया से आ रहा है, मैं बस *0.. का उपयोग करके "0 या अधिक" की गहराई के साथ कुछ करूँगा, जैसे:

MATCH (manager:Person {name:'Bob'}) 
OPTIONAL MATCH (manager)-[:MANAGES]->(:Office)<-[:MERGES_INTO*0..]-(:Office)<-[:WORKS_WITH]-(p:Person)
RETURN p

मैं ग्रेमलिन में उसी तरह की चीज़ कैसे प्राप्त करूं? भले ही मैं ओपन एंडेड नहीं कर सकता, लेकिन कुछ मनमानी सीमा (जैसे, 1 से 10) तक 1 कर सकता था, यह काम करेगा। यह शायद कोई फर्क नहीं पड़ेगा, लेकिन मैं वास्तविक ग्राफ डेटाबेस के लिए एडब्ल्यूएस नेपच्यून का उपयोग करूँगा।

2
Michael Oryl 24 सितंबर 2020, 16:28

1 उत्तर

सबसे बढ़िया उत्तर

ग्रेमलिन के बारे में प्रश्न पूछते समय, आपके ग्राफ की एक तस्वीर अच्छी है, लेकिन एक स्क्रिप्ट जो कुछ नमूना डेटा प्रदान करती है वह और भी बेहतर है - जैसे:

g.addV('person').property('name','michael').as('mi').
  addV('person').property('name','john').as('jo').
  addV('person').property('name','rich').as('ri').
  addV('person').property('name','bob').as('bo').
  addV('person').property('name','matt').as('ma').
  addV('person').property('name','ron').as('ro').
  addV('person').property('name','joe').as('joe').
  addV('person').property('name','ben').as('be').
  addV('person').property('name','judy').as('ju').
  addV('office').property('name','111').as('111').
  addV('office').property('name','356').as('356').
  addV('office').property('name','279').as('279').
  addV('office').property('name','kc5').as('kc5').
  addE('mergesInto').from('kc5').to('279').
  addE('mergesInto').from('279').to('356').
  addE('mergesInto').from('356').to('111').
  addE('worksWith').from('mi').to('111').
  addE('worksWith').from('jo').to('111').
  addE('worksWith').from('ri').to('111').
  addE('worksWith').from('bo').to('111').
  addE('manages').from('bo').to('111').
  addE('worksWith').from('ma').to('279').
  addE('manages').from('ma').to('279').
  addE('worksWith').from('joe').to('279').
  addE('worksWith').from('be').to('279').
  addE('worksWith').from('ju').to('279').
  addE('worksWith').from('ro').to('kc5').iterate()

जहाँ union() आप जो करना चाहते हैं, उसके लिए आपकी प्रवृत्ति सही नहीं है। मैं repeat() पसंद करूंगा:

gremlin> g.V().has('person','name','bob').
......1>   out('manages').
......2>   repeat(__.in('worksWith','mergesInto')).
......3>     emit(hasLabel('person')).
......4>   values('name')
==>bob
==>michael
==>john
==>rich
==>matt
==>joe
==>ben
==>judy
==>ron

इस तरह यह मनमाना गहराई तक जाता है (हालाँकि हम समस्याओं से बचने के लिए किसी प्रकार की समझदार सीमा निर्धारित करने की सलाह देते हैं यदि आप कहीं अप्रत्याशित चक्र में चलते हैं) और यह बहुत अधिक संक्षिप्त है। emit() के उपयोग पर ध्यान दें, जो यह नियंत्रित करता है कि repeat() से किस प्रकार के शीर्ष लौटाए जाते हैं - यदि आप उस फ़िल्टर को शामिल नहीं करते हैं तो आप "कार्यालय" कोने भी वापस कर देंगे।

3
stephen mallette 24 सितंबर 2020, 14:19