

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Funzionalità `explain` di openCypher
<a name="access-graph-opencypher-explain"></a>

La funzionalità `explain` di openCypher è uno strumento self-service di Amazon Neptune che consente di comprendere l'approccio di esecuzione adottato dal motore Neptune. Per richiamare explain, si passa un parametro a una richiesta [HTTPS](access-graph-opencypher-queries.md) openCypher con `explain=mode`, dove il valore `mode` può essere uno dei seguenti:

****
+ **`static`**: in modalità `static`, `explain` visualizza solo la struttura statica del piano di query. Non esegue effettivamente la query.
+ **`dynamic`**: in modalità `dynamic`, `explain` esegue anche la query e include gli aspetti dinamici del piano di query. Questi aspetti potrebbero includere il numero di associazioni intermedie che passano attraverso gli operatori, il rapporto tra le associazioni in entrata e quelle in uscita e il tempo totale impiegato da ogni operatore.
+ **`details`**: in modalità `details`, `explain` visualizza le informazioni mostrate in modalità dynamic oltre a dettagli aggiuntivi, come la stringa di query openCypher effettiva e il calcolo dell'intervallo stimato per il modello sottostante un operatore join.

  

Ad esempio, utilizzando `POST` la modalità with: `dynamic`

------
#### [ AWS CLI ]

```
aws neptunedata execute-open-cypher-explain-query \
  --endpoint-url https://your-neptune-endpoint:port \
  --open-cypher-query "MATCH (n) RETURN n LIMIT 1" \
  --explain-mode dynamic
```

Per ulteriori informazioni, vedere [execute-open-cypher-explain-query](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/execute-open-cypher-explain-query.html) nel AWS CLI Command Reference.

------
#### [ SDK ]

```
import boto3
from botocore.config import Config

client = boto3.client(
    'neptunedata',
    endpoint_url='https://your-neptune-endpoint:port',
    config=Config(read_timeout=None, retries={'total_max_attempts': 1})
)

response = client.execute_open_cypher_explain_query(
    openCypherQuery='MATCH (n) RETURN n LIMIT 1',
    explainMode='dynamic'
)

print(response['results'].read().decode('utf-8'))
```

Per esempi AWS SDK in altre lingue, consulta. [AWS SDK](access-graph-opencypher-sdk.md)

------
#### [ awscurl ]

```
awscurl https://your-neptune-endpoint:port/openCypher \
  --region us-east-1 \
  --service neptune-db \
  -X POST \
  -d "query=MATCH (n) RETURN n LIMIT 1" \
  -d "explain=dynamic"
```

**Nota**  
Questo esempio presuppone che le AWS credenziali siano configurate nel proprio ambiente. Sostituisci *us-east-1* con la regione del tuo cluster Neptune.

------
#### [ curl ]

```
curl https://your-neptune-endpoint:port/openCypher \
  -d "query=MATCH (n) RETURN n LIMIT 1" \
  -d "explain=dynamic"
```

------

## Limitazioni per `explain` di openCypher in Neptune
<a name="access-graph-opencypher-explain-limitations"></a>

Il rilascio corrente di explain di openCypher presenta le seguenti limitazioni:
+ I piani di explain sono attualmente disponibili solo per le query che eseguono operazioni di sola lettura. Le query che eseguono qualsiasi tipo di mutazione, come `CREATE`, `DELETE`, `MERGE`, `SET` e così via non sono supportate.
+ Gli operatori e l'output di un piano specifico potrebbero cambiare nei rilasci futuri.

## Operatori DFE nell'output di `explain` di openCypher
<a name="access-graph-opencypher-dfe-operators"></a>

Per utilizzare le informazioni fornite dalla funzionalità `explain` di openCypher, è necessario comprendere alcuni dettagli su come funziona il [motore di query DFE](neptune-dfe-engine.md) (DFE è il motore utilizzato da Neptune per elaborare le query openCypher).

Il motore DFE traduce ogni query SPARQL in una pipeline di operatori. Partendo dal primo operatore, le soluzioni intermedie passano da un operatore all'altro attraverso questa pipeline di operatori. Ogni riga della tabella di explain rappresenta un risultato, fino al punto di valutazione.

Gli operatori che possono essere presenti in un piano di query DFE sono i seguenti:

**DFEApply**— Esegue la funzione specificata nella sezione degli argomenti, sul valore memorizzato nella variabile specificata

**DFEBindRelazione**: unisce le variabili con i nomi specificati

**DFEChunkLocalSubQuery**— Si tratta di un'operazione non bloccante che funge da involucro per l'esecuzione delle sottoquery.

**DFEDistinctColonna** — Restituisce il sottoinsieme distinto dei valori di input in base alla variabile specificata.

**DFEDistinctRelazione**: restituisce il sottoinsieme distinto delle soluzioni di input in base alla variabile specificata.

**DFEDrain**— Viene visualizzato alla fine di una sottoquery e funge da passaggio di terminazione per quella sottoquery. Il numero di soluzioni viene registrato come `Units In`. `Units Out` è sempre zero.

**DFEForwardValore**: copia tutti i blocchi di input direttamente come blocchi di output da passare al relativo operatore a valle.

**DFEGroupByHashIndex**— Esegue un'operazione di raggruppamento sulle soluzioni di input in base a un indice hash calcolato in precedenza (utilizzando l'operazione). `DFEHashIndexBuild` Analogamente a un output, l'input specificato viene esteso di una colonna contenente una chiave di gruppo per ogni soluzione di input.

**DFEHashIndexBuild**— Crea un indice hash su un insieme di variabili come effetto collaterale. Questo indice hash viene in genere riutilizzato nelle operazioni successive. Consulta `DFEHashIndexJoin` o `DFEGroupByHashIndex` per informazione su dove potrebbe essere necessario utilizzare questo indice.

**DFEHashIndexJoin**— Esegue un join sulle soluzioni in entrata rispetto a un indice hash creato in precedenza. Consulta `DFEHashIndexBuild` per informazioni su dove potrebbe essere necessario creare questo indice.

**DFEJoinEsiste**: accetta una relazione di input sinistra e destra e mantiene i valori della relazione di sinistra che hanno un valore corrispondente nella relazione destra, come definito dalle variabili di join specificate. 

****: si tratta di un'operazione non bloccante che funge da wrapper per una sottoquery, consentendone l'esecuzione ripetuta per l'utilizzo nei cicli.

**DFEMergeChunks**: si tratta di un'operazione di blocco che combina i blocchi dell'operatore a monte in un unico blocco di soluzioni da passare all'operatore a valle (inverso di). `DFESplitChunks`

**DFEMinus**— Accetta una relazione di input sinistra e destra e mantiene i valori della relazione di sinistra che non hanno un valore corrispondente nella relazione destra, come definito dalle variabili di join fornite. Se non vi è alcuna sovrapposizione nelle variabili tra entrambe le relazioni, questo operatore restituisce semplicemente la relazione di input sinistra.

**DFENotEsiste**: accetta una relazione di input sinistra e destra e mantiene i valori della relazione di sinistra che non hanno un valore corrispondente nella relazione destra, come definito dalle variabili di join fornite. Se non vi è alcuna sovrapposizione nelle variabili in entrambe le relazioni, questo operatore restituisce una relazione vuota.

**DFEOptionalJoin**: esegue un join esterno sinistro (chiamato anche join OPZIONALE): le soluzioni dal lato sinistro che hanno almeno un partner di unione sul lato destro vengono unite e le soluzioni dal lato sinistro senza partner di unione sul lato destro vengono inoltrate così come sono. Questa è un'operazione bloccante.

**DFEPipelineUnisci**: unisce l'input allo schema di tuple definito dall'argomento. `pattern`

**DFEPipelineRangeCount**— Conta il numero di soluzioni che corrispondono a un determinato modello e restituisce una singola soluzione unidirezionale contenente il valore di conteggio.

**DFEPipelineScansione**: esegue la scansione del database alla ricerca dell'`pattern`argomento specificato, con o senza un determinato filtro sulle colonne.

**DFEProject**— Richiede più colonne di input e proietta solo le colonne desiderate.

**DFEReduce**— Esegue la funzione di aggregazione specificata su variabili specificate.

DFERelationalJoin - **Unisce** l'input dell'operatore precedente in base alle chiavi dello schema specificate utilizzando un merge join. Questa è un'operazione bloccante.

**DFERouteChunks**: preleva i blocchi di input dal suo singolo bordo in entrata e li indirizza lungo i suoi molteplici bordi in uscita.

**DFESelectRighe**: questo operatore preleva selettivamente le righe dalle soluzioni di relazione di input sinistro per inoltrarle all'operatore a valle. Le righe selezionate in base agli identificatori di riga forniti nella relazione di input destra dell'operatore.

**DFESerialize**— Serializza i risultati finali di una query in una serializzazione di stringhe JSON, mappando ogni soluzione di input al nome di variabile appropriato. Per i risultati di nodi ed edge, questi risultati vengono serializzati in una mappa delle proprietà e dei metadati delle entità.

**DFESort**— Accetta una relazione di input e produce una relazione ordinata in base alla chiave di ordinamento fornita.

**DFESplitByGroup**— Divide ogni singolo blocco di input da un bordo di ingresso in blocchi di output più piccoli corrispondenti ai gruppi di righe identificati dalla riga IDs dal blocco di input corrispondente dall'altro bordo in entrata.

**DFESplitChunk: divide ogni singolo blocco di input in blocchi** di output più piccoli (inversi di). `DFEMergeChunks`

**DFEStreamingHashIndexBuild**— `DFEHashIndexBuild` Versione in streaming di.

**DFEStreamingGroupByHashIndex**— Versione in streaming di`DFEGroupByHashIndex`.

**DFESubquery**— Questo operatore appare all'inizio di tutti i piani e riassume le parti del piano eseguite sul [motore DFE](neptune-dfe-engine.md), che è l'intero piano per OpenCypher.

**DFESymmetricHashJoin**— Unisce l'input dell'operatore precedente in base alle chiavi del pattern specificato utilizzando un hash join. Questa è un'operazione non bloccante.

**DFESync**— Questo operatore è un operatore di sincronizzazione che supporta piani non bloccanti. Accetta le soluzioni da due edge in entrata e le inoltra agli edge a valle appropriati. Ai fini della sincronizzazione, gli input lungo uno di questi edge possono essere bufferizzati internamente. 

**DFETee**— Si tratta di un operatore di filiale che invia lo stesso set di soluzioni a più operatori.

**DFETermRisoluzione**: esegue un'operazione di localizzazione o globalizzazione sui relativi input, generando colonne rispettivamente di identificatori localizzati o globalizzati.

****: espande gli elenchi di valori da una colonna di input nella colonna di output come singoli elementi.

**DFEUnion**— Accetta due o più relazioni di input e produce un'unione di tali relazioni utilizzando lo schema di output desiderato.

**SolutionInjection**— Viene visualizzato prima di tutto il resto nell'output di spiegazione, con un valore di 1 nella colonna Units Out. Tuttavia, non genera alcuna operazione e in realtà non inserisce alcuna soluzione nel motore DFE.

**TermResolution**— Appare alla fine dei piani e traduce gli oggetti dal motore Neptune in oggetti OpenCypher.

## Colonne nell'output di `explain` di openCypher
<a name="access-graph-opencypher-explain-columns"></a>

Le informazioni sul piano di query che Neptune genera come output di explain di openCypher contengono tabelle con un operatore per riga. La tabella contiene le seguenti colonne:

**ID**: ID numerico di questo operatore nel piano.

**Out \$11** (e **Out \$12**): ID degli operatori downstream rispetto a questo operatore. Possono esserci al massimo due operatori downstream.

**Name**: nome di questo operatore.

**Arguments**: qualsiasi dettaglio rilevante per l'operatore. Ciò include elementi come lo schema di input, lo schema di output, il modello (per `PipelineScan` e `PipelineJoin`) e così via.

**Mode**: etichetta che descrive il comportamento fondamentale dell'operatore. Questa colonna è per lo più vuota (`-`). Un'eccezione è `TermResolution`, dove mode può essere `id2value_opencypher`, che indica una risoluzione dall'ID al valore openCypher.

**Units In**: numero di soluzioni passate come input a questo operatore. Gli operatori senza operatori upstream, come `DFEPipelineScan`, `SolutionInjections` e `DFESubquery` senza valore statico inserito, avranno valore zero.

**Units Out**: numero di soluzioni prodotte come output di questo operatore. `DFEDrain` è un caso speciale, in cui il numero di soluzioni da eliminare viene registrato in `Units In` e `Units Out` è sempre zero.

**Ratio**: rapporto tra `Units Out` e `Units In`.

**Time (ms)**: tempo della CPU utilizzato da questo operatore, in millisecondi.

## Esempio di base dell'output di explain di openCypher
<a name="access-graph-opencypher-explain-basic-example"></a>

Il seguente è un esempio di base dell'output di `explain` di openCypher. La query è una ricerca a nodo singolo nel set di dati delle rotte aeree per un nodo con il codice dell'aeroporto `ATL` che richiama l'utilizzo della modalità nel formato di output ASCII predefinito. `explain` `details`

Per richiamare questa query: `explain`

------
#### [ AWS CLI ]

```
aws neptunedata execute-open-cypher-explain-query \
  --endpoint-url https://your-neptune-endpoint:port \
  --open-cypher-query "MATCH (n {code: 'ATL'}) RETURN n" \
  --explain-mode details
```

Per ulteriori informazioni, vedere [execute-open-cypher-explain-query](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/execute-open-cypher-explain-query.html) nel AWS CLI Command Reference.

------
#### [ SDK ]

```
import boto3
from botocore.config import Config

client = boto3.client(
    'neptunedata',
    endpoint_url='https://your-neptune-endpoint:port',
    config=Config(read_timeout=None, retries={'total_max_attempts': 1})
)

response = client.execute_open_cypher_explain_query(
    openCypherQuery="MATCH (n {code: 'ATL'}) RETURN n",
    explainMode='details'
)

print(response['results'].read().decode('utf-8'))
```

Per esempi AWS SDK in altre lingue, consulta. [AWS SDK](access-graph-opencypher-sdk.md)

------
#### [ awscurl ]

```
awscurl https://your-neptune-endpoint:port/openCypher \
  --region us-east-1 \
  --service neptune-db \
  -X POST \
  -d "query=MATCH (n {code: 'ATL'}) RETURN n" \
  -d "explain=details"
```

**Nota**  
Questo esempio presuppone che le AWS credenziali siano configurate nel proprio ambiente. Sostituisci *us-east-1* con la regione del tuo cluster Neptune.

------
#### [ curl ]

```
curl https://your-neptune-endpoint:port/openCypher \
  -d "query=MATCH (n {code: 'ATL'}) RETURN n" \
  -d "explain=details"
```

------

L'`explain`output:

```
Query:
MATCH (n {code: 'ATL'}) RETURN n

╔════╤════════╤════════╤═══════════════════╤════════════════════╤═════════════════════╤══════════╤═══════════╤═══════╤═══════════╗
║ ID │ Out #1 │ Out #2 │ Name              │ Arguments          │ Mode                │ Units In │ Units Out │ Ratio │ Time (ms) ║
╠════╪════════╪════════╪═══════════════════╪════════════════════╪═════════════════════╪══════════╪═══════════╪═══════╪═══════════╣
║ 0  │ 1      │ -      │ SolutionInjection │ solutions=[{}]     │ -                   │ 0        │ 1         │ 0.00  │ 0         ║
╟────┼────────┼────────┼───────────────────┼────────────────────┼─────────────────────┼──────────┼───────────┼───────┼───────────╢
║ 1  │ 2      │ -      │ DFESubquery       │ subQuery=subQuery1 │ -                   │ 0        │ 1         │ 0.00  │ 4.00      ║
╟────┼────────┼────────┼───────────────────┼────────────────────┼─────────────────────┼──────────┼───────────┼───────┼───────────╢
║ 2  │ -      │ -      │ TermResolution    │ vars=[?n]          │ id2value_opencypher │ 1        │ 1         │ 1.00  │ 2.00      ║
╚════╧════════╧════════╧═══════════════════╧════════════════════╧═════════════════════╧══════════╧═══════════╧═══════╧═══════════╝


subQuery1
╔════╤════════╤════════╤═══════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════════════════╤══════╤══════════╤═══════════╤═══════╤═══════════╗
║ ID │ Out #1 │ Out #2 │ Name                  │ Arguments                                                                                                    │ Mode │ Units In │ Units Out │ Ratio │ Time (ms) ║
╠════╪════════╪════════╪═══════════════════════╪══════════════════════════════════════════════════════════════════════════════════════════════════════════════╪══════╪══════════╪═══════════╪═══════╪═══════════╣
║ 0  │ 1      │ -      │ DFEPipelineScan       │ pattern=Node(?n) with property 'code' as ?n_code2 and label 'ALL'                                            │ -    │ 0        │ 1         │ 0.00  │ 0.21      ║
║    │        │        │                       │ inlineFilters=[(?n_code2 IN ["ATL"^^xsd:string])]                                                            │      │          │           │       │           ║
║    │        │        │                       │ patternEstimate=1                                                                                            │      │          │           │       │           ║
╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 1  │ 2      │ -      │ DFEChunkLocalSubQuery │ subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#9d84f97c-c3b0-459a-98d5-955a8726b159/graph_1 │ -    │ 1        │ 1         │ 1.00  │ 0.04      ║
╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 2  │ 3      │ -      │ DFEProject            │ columns=[?n]                                                                                                 │ -    │ 1        │ 1         │ 1.00  │ 0.04      ║
╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 3  │ -      │ -      │ DFEDrain              │ -                                                                                                            │ -    │ 1        │ 0         │ 0.00  │ 0.03      ║
╚════╧════════╧════════╧═══════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════════════════╧══════╧══════════╧═══════════╧═══════╧═══════════╝


subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#9d84f97c-c3b0-459a-98d5-955a8726b159/graph_1
╔════╤════════╤════════╤══════════════════════╤════════════════════════════════════════════════════════════╤══════╤══════════╤═══════════╤═══════╤═══════════╗
║ ID │ Out #1 │ Out #2 │ Name                 │ Arguments                                                  │ Mode │ Units In │ Units Out │ Ratio │ Time (ms) ║
╠════╪════════╪════════╪══════════════════════╪════════════════════════════════════════════════════════════╪══════╪══════════╪═══════════╪═══════╪═══════════╣
║ 0  │ 1      │ -      │ DFESolutionInjection │ outSchema=[?n, ?n_code2]                                   │ -    │ 0        │ 1         │ 0.00  │ 0.02      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 1  │ 2      │ 3      │ DFETee               │ -                                                          │ -    │ 1        │ 2         │ 2.00  │ 0.02      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 2  │ 4      │ -      │ DFEDistinctColumn    │ column=?n                                                  │ -    │ 1        │ 1         │ 1.00  │ 0.20      ║
║    │        │        │                      │ ordered=false                                              │      │          │           │       │           ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 3  │ 5      │ -      │ DFEHashIndexBuild    │ vars=[?n]                                                  │ -    │ 1        │ 1         │ 1.00  │ 0.04      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 4  │ 5      │ -      │ DFEPipelineJoin      │ pattern=Node(?n) with property 'ALL' and label '?n_label1' │ -    │ 1        │ 1         │ 1.00  │ 0.25      ║
║    │        │        │                      │ patternEstimate=3506                                       │      │          │           │       │           ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 5  │ 6      │ 7      │ DFESync              │ -                                                          │ -    │ 2        │ 2         │ 1.00  │ 0.02      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 6  │ 8      │ -      │ DFEForwardValue      │ -                                                          │ -    │ 1        │ 1         │ 1.00  │ 0.01      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 7  │ 8      │ -      │ DFEForwardValue      │ -                                                          │ -    │ 1        │ 1         │ 1.00  │ 0.01      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 8  │ 9      │ -      │ DFEHashIndexJoin     │ -                                                          │ -    │ 2        │ 1         │ 0.50  │ 0.35      ║
╟────┼────────┼────────┼──────────────────────┼────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
║ 9  │ -      │ -      │ DFEDrain             │ -                                                          │ -    │ 1        │ 0         │ 0.00  │ 0.02      ║
╚════╧════════╧════════╧══════════════════════╧════════════════════════════════════════════════════════════╧══════╧══════════╧═══════════╧═══════╧═══════════╝
```

Al livello superiore, `SolutionInjection` appare prima di ogni altra cosa, con 1 come valore di Units In. Notare che in realtà non inserisce alcuna soluzione. Si può vedere che l'operatore successivo `DFESubquery` ha 0 come valore di Units Out.

Dopo `SolutionInjection` al livello più alto, ci sono gli operatori `DFESubquery` e `TermResolution`. `DFESubquery` incapsula le parti del piano di esecuzione delle query che viene inviato al [motore DFE](neptune-dfe-engine.md) (per le query openCypher, l'intero piano di esecuzione delle query viene eseguito dal motore DFE). Tutti gli operatori del piano di query sono annidati all'interno di `subQuery1` a cui fa riferimento `DFESubquery`. L'unica eccezione è `TermResolution` che si materializza internamente IDs in oggetti OpenCypher completamente serializzati.

Tutti gli operatori che vengono inviati al motore DFE hanno nomi che iniziano con un prefisso `DFE`. Come accennato in precedenza, l'intero piano di query di openCypher viene eseguito dal motore DFE, quindi, tutti gli operatori tranne l'operatore finale `TermResolution` iniziano con `DFE`.

All'interno di `subQuery1` possono essere presenti zero o più operatori `DFEChunkLocalSubQuery` o `DFELoopSubQuery` che incapsulano una parte del piano di esecuzione inviato che viene eseguito in un meccanismo con limiti di memoria. `DFEChunkLocalSubQuery` qui contiene un solo `SolutionInjection` che viene utilizzato come input per la sottoquery. Per trovare la tabella per tale sottoquery nell'output, cercare `subQuery=graph URI` specificato nella colonna `Arguments` per l'operatore `DFEChunkLocalSubQuery` o `DFELoopSubQuery`.

In `subQuery1`, `DFEPipelineScan` con `ID` 0 analizza il database alla ricerca di un oggetto `pattern` specificato. Il modello cerca un'entità con proprietà `code` salvata come variabile `?n_code2` su tutte le etichette (è possibile filtrare in base a un'etichetta specifica aggiungendo `airport` a `n:airport`). L'argomento `inlineFilters` mostra il filtro per la proprietà `code` uguale a `ATL`.

Successivamente, l'operatore `DFEChunkLocalSubQuery` esegue il join dei risultati intermedi di una sottoquery che contiene `DFEPipelineJoin`. Ciò garantisce che `?n` sia effettivamente un nodo, poiché l'operatore precedente `DFEPipelineScan` cerca qualsiasi entità con la proprietà `code`.