--------------------NOTEBOOK_Ch4_Neighborhoods_dev--------------------
--------------------CELL_MARKDOWN_1--------------------
# ![bono](https://raw.githubusercontent.com/datastax/graph-book/master/notebooks/images/logos/grem-4.png) Chapter 4 
## Badanie sąsiedztw w środowisku roboczym
Autor notatnika: [Denise Gosnell](https://twitter.com/DeniseKGosnell)

Aby przejść do następnego etapu tworzenia aplikacji grafowej, będziemy rozwijać prostą aplikację Customer 360 (C360) z rozdziau 3.  Dodamy kilka warstw, czyli sąsiedztw, do przykładu, aby pokazać nowe koncepcje w myśleniu grafowym.

---------------

**&#9888;** Nie wszystkie komórki rozwijają się domyślnie. Ich treść jest ukryta, jak w przypadku tej komórki. Kliknij oko w prawym rogu komórki, aby wyświetlić i ukryć kod komórki.
--------------------CELL_MARKDOWN_2--------------------
## <div id="topKey"></div>Ten notatnik jest podzielony na cztery części:
#### [Krok 1](#step1): Tworzenie schematu grafu
#### [Krok 2](#step2): Instrukcje wstawiania danych
#### [Krok 3](#step3): Podstawowa nawigacja w Gremlinie
#### [Krok 4](#step4): Zaawansowane aspekty Gremlina: formatowanie wyników zapytania
--------------------CELL_MARKDOWN_3--------------------
## <div id="step1"></div>Krok 1: Tworzenie schematu grafu
[Początek &#x2191;](#topKey)
[Następne: Instrukcje wstawiania danych &#x2193;](#step2)
--------------------CELL_MARKDOWN_4--------------------
Roboczy model danych dla rozdziału 4.:
![ch4_model](https://raw.githubusercontent.com/datastax/graph-book/master/notebooks/images/schema/ch4_schema.png "Dodanie kilku sąsiedztw danych do przykładu z rozdziału 3.")
--------------------CELL_MARKDOWN_5--------------------
#### Tworzenie etykiet wierzchołków
--------------------CELL_GREMLIN_6--------------------
// nowe etykiety wierzchołków dla rozdziału 4.
schema.vertexLabel('Transaction').
       ifNotExists().
       partitionBy('transaction_id', Int).
       property('transaction_type', Text).
       property('timestamp', Text).
       create();

schema.vertexLabel('Vendor').
       ifNotExists().
       partitionBy('vendor_id', Int).
       property("vendor_name", Text).
       create();
       
// etykiety wierzchołków z rozdziału 3
schema.vertexLabel('Customer').
       ifNotExists().
       partitionBy('customer_id', Text).
       property('name', Text).
       create();

schema.vertexLabel('Account').
       ifNotExists().
       partitionBy('acct_id', Text).
       create();

schema.vertexLabel('Loan').
       ifNotExists().
       partitionBy('loan_id', Text).
       create();

schema.vertexLabel('CreditCard').
       ifNotExists().
       partitionBy('cc_num', Text).
       create();
--------------------CELL_MARKDOWN_7--------------------
#### Tworzenie etykiet krawędzi
--------------------CELL_GREMLIN_8--------------------
// nowe krawędzie dla rozdziału 4.
schema.edgeLabel('withdraw_from').
       ifNotExists().
       from('Transaction').
       to('Account').
       create();

schema.edgeLabel('deposit_to').
       ifNotExists().
       from('Transaction').
       to('Account').
       create();

schema.edgeLabel('pay').
       ifNotExists().
       from('Transaction').
       to('Loan').
       create();

schema.edgeLabel('charge').
       ifNotExists().
       from('Transaction').
       to('CreditCard').
       create();

schema.edgeLabel('pay').
       ifNotExists().
       from('Transaction').
       to('Vendor').
       create();
       
// krawędzie z rozdziału 3.
schema.edgeLabel('owes').
       ifNotExists().
       from('Customer').
       to('Loan').
       create();
       
schema.edgeLabel('uses').
       ifNotExists().
       from('Customer').
       to('CreditCard').
       create();

schema.edgeLabel('owns').
       ifNotExists().
       from('Customer').
       to('Account').
       property('role', Text).
       create();
--------------------CELL_MARKDOWN_9--------------------
## <div id="step2"></div>Krok 2: Instrukcje wstawiania danych
[Początek &#8593;](#topKey)
[Wstecz: Schemat &#x21b5;](#step1)
[Następne: Podstawowa nawigacja w Gremlinie &#x2193;](#step3)
--------------------CELL_MARKDOWN_10--------------------
#### Opcja A: Jeśli chcesz *tylko wykonać kilka poleceń w programie Studio*, aby przejść do poniższych zapytań...
Otwórz notatnik o nazwie "Ch4_DataGeneration" i wykonaj zawarte w nim instrukcje. Wstawisz dane, na podstawie których będą działać poniższe zapytania, ale wyniki będą się różnić od wyników z książki. Różnice wynikają z pewnej randomizacji podczas tworzenia danych.

#### Opcja B: Wybierz ją jeśli chcesz, aby dane były *identyczne* jak wyniki w tekście. 
Wykonaj poniższe wyniki, aby zaimportować identyczne dane narzędziem DataStax Bulk Loader.

--------------------CELL_MARKDOWN_11--------------------
## <div id="step3"></div>Krok 3: Podstawowa nawigacja w Gremlinie
[Początek &#8593;](#topKey)
[Wstecz: Instructions for Data Loading &#x21b5;](#step2)
[Następne: Zaawansowane aspekty Gremlina: formatowanie wyników zapytania &#x2193;](#step4)
--------------------CELL_MARKDOWN_12--------------------
#### 3.a) Wyszukanie dwudziestu ostatnich transakcji wykonanych na koncie Michaela.
--------------------CELL_GREMLIN_13--------------------
dev.V().has("Customer", "customer_id", "customer_0"). // klient 
        out("owns").                       // przejście do jego konta
        in("withdraw_from", "deposit_to"). // przejście do wszystkich transakcji 
        order().                           // sortowanie wierzchołków
          by(values("timestamp"), desc).   // według właściwości timestamp, w kolejności malejącej
        limit(20).                         // wybór 20 najnowszych
        values("transaction_id")           // zwracanie wartości właściwości transaction_id
--------------------CELL_MARKDOWN_14--------------------
### ![bono](https://i.ibb.co/z7gfj7F/gremlin-unicorn.png) Dodatkowe zapytanie, znajdujące się tylko w notatniku!
Formatowanie wyników ostatniego zapytania, aby pokazać czas i id transakcji
--------------------CELL_GREMLIN_15--------------------
dev.V().has("Customer", "customer_id", "customer_0"). // klient
        out("owns").                       // przejście do jego konta
        in("withdraw_from", "deposit_to"). // przejście do wszystkich transakcji
        order().                           // sortowanie wierzchołków
          by(values("timestamp"), desc).   // według właściwości timestamp, w kolejności malejącej
        limit(20).                         // wybór 20 najnowszych
        project("transaction_id", "timestamp"). // tworzenie mapy z 2 kluczami
              by("transaction_id"). // wartości pierwszego klucza
              by("timestamp")       // wartości drugiego klucza
--------------------CELL_MARKDOWN_16--------------------
#### 3.b) Znajdź sklepy, w których Michael dokonał zakupów w grudniu 2020 roku i ustal częstotliwość zakupów.
--------------------CELL_GREMLIN_17--------------------
dev.V().has("Customer", "customer_id", "customer_0"). // klient
        out("uses").                         // przejście do jego karty kredytowej
        in("charge").                        // przejście do wszystkich transakcji
        has("timestamp",                     // uwzględnienie tylko transakcji
            between("2020-12-01T00:00:00Z",  // z grudnia 2020 
                    "2021-01-01T00:00:00Z")).
        out("pay").                          // przejście do sprzedawców 
        groupCount().                        // zgrupowanie ich i zliczenie
          by("vendor_name")                  // na podstawie nazwy
--------------------CELL_GREMLIN_18--------------------
dev.V().has("Customer", "customer_id", "customer_0"). 
        out("uses").                         
        in("charge").                        
        has("timestamp",                    
            between("2020-12-01T00:00:00Z",  
                    "2021-01-01T00:00:00Z")).
        out("pay").                          
        groupCount().                        
          by("vendor_name").                 
        order(local).         // porządkowanie obiektu mapy
          by(values, desc)    // według wartości, malejąco
--------------------CELL_MARKDOWN_19--------------------
#### 3.c) Znajdź i uaktualnij transakcje, mające największe znaczenie dla Jamiego i Aaliyah: spłaty kredytu hipotecznego za pośrednictwem konta.
--------------------CELL_MARKDOWN_20--------------------
Znajdź transakcje Aaliyah, które dotyczą spłat kredytu
--------------------CELL_GREMLIN_21--------------------
dev.V().has("Customer", "customer_id", "customer_4").// pobieranie wierzchołka Aaliyah
        out("owns").                      // przejście do konta
        in("withdraw_from").              // uwzględniamy tylko wypłaty
        out("pay").                       // przejście do kredytów lub sprzedawców
        hasLabel("Loan").                 // ograniczenie tylko do kredytów
        groupCount().                     // liczenie wierzchołków kredytów
          by("loan_id")                   // na podstawie loan_id
--------------------CELL_MARKDOWN_22--------------------
Znajdź i uaktualnij transakcje, które są najważniejsze dla Aaliyah: transakcje spłat kredytu hipotecznego <tt>loan_18</tt> wykonane na jej koncie. 
--------------------CELL_GREMLIN_23--------------------
dev.V().has("Customer", "customer_id", "customer_4").    // pobieranie wierzchołka Aaliyah
        out("owns").                                     // przejście do konta
         in("withdraw_from").                            // uwzględniamy tylko wypłaty
         filter(
                out("pay").                              // przejście do kredytów lub sprzedawców
                has("Loan", "loan_id", "loan_18")) .     // zatrzymujemy tylko loan_18
         property("transaction_type",    // krok mutujący: ustawiamy właściwość "transaction_type"
                  "mortgage_payment").   // na "mortgage_payment"
         values("transaction_id", "transaction_type")     // zwraca transakcję i typ  
--------------------CELL_MARKDOWN_24--------------------
Weryfikujemy, czy nie uaktualniliśmy wszystkich transakcji
--------------------CELL_GREMLIN_25--------------------
// sprawdzamy czy nie uaktualniliśmy wszystkich transakcji
dev.V().has("Customer", "customer_id", "customer_4"). // wierzchołek klienta
        out("owns").                      // wierzchołek konta
        in("withdraw_from").              // wszystkie wypłaty
        groupCount().                     // grupowanie i liczenie wierzchołków
           by(values("transaction_type"))  // według typu transakcji
--------------------CELL_MARKDOWN_26--------------------
## <div id="step4"></div>Krok 4: Zaawansowane aspekty Gremlina: formatowanie wyników zapytania
[Początek &#8593;](#topKey)
[Wstecz: Podstawowa nawigacja w Gremlinie &#x21b5;](#step3)
--------------------CELL_MARKDOWN_27--------------------
#### Zapytanie: Czy ktoś ma to samo konto, kredyt lub kartę kredytową co Michael?
**Wymagania dotyczące wyników:** wyniki mają poprawny format JSON
**Co będziemy robić:** iteracyjnie rozbudowywać zapytanie, aby zrozumieć działanie kroku project()
--------------------CELL_GREMLIN_28--------------------
dev.V().has("Customer", "customer_id", "customer_0").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(constant("imię lub brak posiadacza kart kredytowych")).
          by(constant("imię lub brak posiadacza kont")).
          by(constant("imię lub brak posiadacza kredytów"))
--------------------CELL_GREMLIN_29--------------------
dev.V().has("Customer", "customer_id", "customer_0").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
             values("name")).
          by(constant("imię lub brak posiadacza kont")).
          by(constant("imię lub brak posiadacza kredytów"))
--------------------CELL_GREMLIN_30--------------------
dev.V().has("Customer", "customer_id", "customer_0").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
             values("name")).
          by(out("owns").
             in("owns").
             values("name")).
          by(constant("imię lub brak posiadacza kredytów"))
--------------------CELL_MARKDOWN_31--------------------
#### Wprowadzenie do kroku fold. 

<tt>fold()</tt> jest krokiem barierowym, który wymusza zakończenie działania wszystkich przejść. Zmnienia również typ danych wyników na listę.
--------------------CELL_GREMLIN_32--------------------
dev.V().has("Customer", "customer_id", "customer_0").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
             values("name").
             fold()).
          by(out("owns").
             in("owns").
             values("name").
             fold()).
          by(constant("name or no owner for loans"))
--------------------CELL_GREMLIN_33--------------------
dev.V().has("Customer", "customer_id", "customer_0").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
             values("name").
             fold()).
          by(out("owns").
             in("owns").
             values("name").
             fold()).
          by(out("owes").
             in("owes").
             values("name").
             fold())
--------------------CELL_MARKDOWN_34--------------------
#### Usunięcie Michaela z wyników

Wprowadzenie do wzorca <tt>where(neq())</tt>

--------------------CELL_GREMLIN_35--------------------
dev.V().has("Customer", "customer_id", "customer_0").as("michael").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
               where(neq("michael")).
             values("name").
             fold()).
          by(out("owns").
             in("owns").
               where(neq("michael")).
             values("name").
             fold()).
          by(out("owes").
             in("owes").
               where(neq("michael")).
             values("name").
             fold())
           
           
--------------------CELL_MARKDOWN_36--------------------
### Zaawansowany Gremlin 2: bloki try/catch z krokiem <tt>coalesce()</tt>

Zapytanie: Czy ktoś ma to samo konto, kredyt lub kartę kredytową co Michael?
RWymagania dotyczące wyników: wyniki są **nie pustymi** danymi w formacie JSON
--------------------CELL_MARKDOWN_37--------------------
**Dlaczego to robimy?**: 

Aplikacja może nie zadziałać jeśli lista jest pusta. Czasem lepiej, jeśli wynik zawiera wartość o pewnym znaczeniu. W tym celu potrzebna jest logika it/else lub try/catch. 

Zaimplementujemy logikę try/catch. Możesz wykonać ten sam proces za pomocą logiki if/else z krokiem <tt>choose()</tt>.
--------------------CELL_MARKDOWN_38--------------------
Wykonajmy logikę dla pierwszego modulatora <tt>by()</tt>.
--------------------CELL_GREMLIN_39--------------------
dev.V().has("Customer", "customer_id", "customer_0").as("michael").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
               where(neq("michael")).
             values("name").
             fold()).
           by(constant("imię lub brak posiadacza kont")).
           by(constant("imię lub brak posiadacza kredytów"))
--------------------CELL_GREMLIN_40--------------------
dev.V().has("Customer", "customer_id", "customer_0").as("michael").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
               where(neq("michael")).
             values("name").
             fold().
             coalesce(constant("tryBlockLogic"),
                      constant("catchBlockLogic"))).
           by(constant("imię lub brak posiadacza kont")).
           by(constant("imię lub brak posiadacza kredytów"))
--------------------CELL_GREMLIN_41--------------------
dev.V().has("Customer", "customer_id", "customer_0").as("michael").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
               where(neq("michael")).
             values("name").
             fold().
             coalesce(unfold(), 
                      constant("NoOtherUsers"))).
          by(constant("imię lub brak posiadacza kont")).
          by(constant("imię lub brak posiadacza kredytów"))
--------------------CELL_GREMLIN_42--------------------
dev.V().has("Customer", "customer_id", "customer_0").as("michael").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
          by(out("uses").
             in("uses").
               where(neq("michael")).
             values("name").
             fold().
             coalesce(unfold(), 
                      constant("NoOtherUsers").fold())).
          by(constant("imię lub brak posiadacza kont")).
          by(constant("imię lub brak posiadacza kredytów"))
--------------------CELL_MARKDOWN_43--------------------
Po utworzeniu wzorca dla pierwszego modulatora <tt>by()</tt> powtórzmy go w następnych dwóch modulatorach <tt>by()</tt>.
--------------------CELL_GREMLIN_44--------------------
dev.V().has("Customer", "customer_id", "customer_0").as("michael").
        project("CreditCardUsers", "AccountOwners", "LoanOwners").
        by(out("uses").
           in("uses").
             where(neq("michael")).
           values("name").
           fold().
           coalesce(unfold(),
                    constant("NoOtherUsers")).fold()).
         by(out("owns").
           in("owns").
             where(neq("michael")).
           values("name").
           fold().
           coalesce(unfold(),
                    constant("NoOtherUsers")).fold()).
        by(out("owes").
           in("owes").
             where(neq("michael")).
           values("name").
           fold().
           coalesce(unfold(),
                    constant("NoOtherUsers")).fold())
--------------------CELL_MARKDOWN_45--------------------
# ![grem](https://i.ibb.co/grXtFgv/datastax-gremlin.png) Open Challenge: 
#### Jak sformatować to zapytanie za pomocą logiki if/else i kroku <tt>choose()</tt>?
--------------------CELL_MARKDOWN_46--------------------
#### Koniec notatnika
