Query SQL per l'API di DocumentDB di Azure Cosmos DBSQL queries for Azure Cosmos DB DocumentDB API

Microsoft Azure Cosmos DB supporta l'esecuzione di query di documenti mediante SQL (Structured Query Language) come linguaggio di query JSON.Microsoft Azure Cosmos DB supports querying documents using SQL (Structured Query Language) as a JSON query language. Cosmos DB è effettivamente privo di schema.Cosmos DB is truly schema-free. Grazie all'impegno nei confronti del modello di dati JSON direttamente nel motore del database, fornisce l'indicizzazione automatica dei documenti JSON senza richiedere schemi espliciti o la creazione di indici secondari.By virtue of its commitment to the JSON data model directly within the database engine, it provides automatic indexing of JSON documents without requiring explicit schema or creation of secondary indexes.

Nella progettazione del linguaggio di query per Cosmos DB sono stati tenuti in considerazione due obiettivi:While designing the query language for Cosmos DB, we had two goals in mind:

  • Invece di inventare un nuovo linguaggio di query JSON, è stato introdotto il supporto del linguaggio SQL.Instead of inventing a new JSON query language, we wanted to support SQL. SQL è uno dei linguaggi di query più familiari e popolari.SQL is one of the most familiar and popular query languages. Il linguaggio di query SQL di Cosmos DB fornisce un modello di programmazione formale per le query complesse sui documenti JSON.Cosmos DB SQL provides a formal programming model for rich queries over JSON documents.
  • Poiché un database di documenti JSON può eseguire JavaScript direttamente nel motore di database, l'obiettivo era di usare il modello di programmazione di JavaScript come base per il linguaggio di query.As a JSON document database capable of executing JavaScript directly in the database engine, we wanted to use JavaScript's programming model as the foundation for our query language. L'API SQL di DocumentDB trova le sue radici nel sistema di tipi, nella valutazione delle espressioni e nella chiamata di funzioni di JavaScript.The DocumentDB API SQL is rooted in JavaScript's type system, expression evaluation, and function invocation. Questo rappresenta a sua volta un modello di programmazione naturale per le proiezioni relazionali, la navigazione gerarchica attraverso i documenti JSON, i self join, query spaziali e la chiamata di funzioni definite dall'utente (UDF) scritte interamente in JavaScript, tra le altre funzionalità.This in-turn provides a natural programming model for relational projections, hierarchical navigation across JSON documents, self joins, spatial queries, and invocation of user-defined functions (UDFs) written entirely in JavaScript, among other features.

Queste capacità costituiscono la chiave per la riduzione dell'attrito tra l'applicazione e il database e sono di importanza critica per la produttività degli sviluppatori.We believe that these capabilities are key to reducing the friction between the application and the database and are crucial for developer productivity.

Si consiglia di iniziare guardando il video seguente, in cui Aravind Ramachandran mostra le funzionalità di query di Cosmos DB, e visitando la pagina Query Playground, in cui è possibile provare Cosmos DB ed eseguire query SQL rispetto a un set di dati predefinito.We recommend getting started by watching the following video, where Aravind Ramachandran shows Cosmos DB's querying capabilities, and by visiting our Query Playground, where you can try out Cosmos DB and run SQL queries against our dataset.

Tornare quindi a questo articolo, dove inizia un'esercitazione sulle query SQL in cui verranno illustrati alcuni semplici documenti JSON e comandi SQL.Then, return to this article, where we start with a SQL query tutorial that walks you through some simple JSON documents and SQL commands.

Guida introduttiva ai comandi SQL in Cosmos DBGetting started with SQL commands in Cosmos DB

Per osservare il funzionamento del linguaggio SQL di Cosmos DB, si inizierà con alcuni semplici documenti JSON e si procederà eseguendo alcune semplici query su tali documenti.To see Cosmos DB SQL at work, let's begin with a few simple JSON documents and walk through some simple queries against it. Considerare questi due documenti JSON come se riguardassero due famiglie.Consider these two JSON documents about two families. Con Cosmos DB, non è necessario creare schemi o indici secondari in maniera esplicita.With Cosmos DB, we do not need to create any schemas or secondary indices explicitly. È sufficiente inserire i documenti JSON in una raccolta di Cosmos DB e successivamente eseguire una query.We simply need to insert the JSON documents to a Cosmos DB collection and subsequently query. In questo caso è illustrato un semplice documento JSON relativo alla famiglia Andersen: i genitori, i figli (e i loro animali domestici), l'indirizzo e le informazioni di registrazione.Here we have a simple JSON document for the Andersen family, the parents, children (and their pets), address, and registration information. Il documento contiene stringhe, numeri, valori booleani, matrici e proprietà annidate.The document has strings, numbers, Booleans, arrays, and nested properties.

DocumentoDocument

{
  "id": "AndersenFamily",
  "lastName": "Andersen",
  "parents": [
     { "firstName": "Thomas" },
     { "firstName": "Mary Kay"}
  ],
  "children": [
     {
         "firstName": "Henriette Thaulow", 
         "gender": "female", 
         "grade": 5,
         "pets": [{ "givenName": "Fluffy" }]
     }
  ],
  "address": { "state": "WA", "county": "King", "city": "seattle" },
  "creationDate": 1431620472,
  "isRegistered": true
}

Ecco un secondo documento con una sottile differenza: vengono usati givenName e familyName invece di firstName e lastName.Here's a second document with one subtle difference – givenName and familyName are used instead of firstName and lastName.

DocumentoDocument

{
  "id": "WakefieldFamily",
  "parents": [
      { "familyName": "Wakefield", "givenName": "Robin" },
      { "familyName": "Miller", "givenName": "Ben" }
  ],
  "children": [
      {
        "familyName": "Merriam", 
        "givenName": "Jesse", 
        "gender": "female", "grade": 1,
        "pets": [
            { "givenName": "Goofy" },
            { "givenName": "Shadow" }
        ]
      },
      { 
        "familyName": "Miller", 
         "givenName": "Lisa", 
         "gender": "female", 
         "grade": 8 }
  ],
  "address": { "state": "NY", "county": "Manhattan", "city": "NY" },
  "creationDate": 1431620462,
  "isRegistered": false
}

A questo punto è possibile provare a eseguire alcune query a fronte di questi dati per comprendere alcuni aspetti chiave dell'API SQL di DocumentDB.Now let's try a few queries against this data to understand some of the key aspects of DocumentDB API SQL. Ad esempio, la query seguente restituisce i documenti in cui il campo ID corrisponde a AndersenFamily.For example, the following query returns the documents where the id field matches AndersenFamily. Poiché si tratta di un'istruzione SELECT *, l'output della query è il documento JSON completo:Since it's a SELECT *, the output of the query is the complete JSON document:

QueryQuery

SELECT * 
FROM Families f 
WHERE f.id = "AndersenFamily"

RisultatiResults

[{
    "id": "AndersenFamily",
    "lastName": "Andersen",
    "parents": [
       { "firstName": "Thomas" },
       { "firstName": "Mary Kay"}
    ],
    "children": [
       {
           "firstName": "Henriette Thaulow", "gender": "female", "grade": 5,
           "pets": [{ "givenName": "Fluffy" }]
       }
    ],
    "address": { "state": "WA", "county": "King", "city": "seattle" },
    "creationDate": 1431620472,
    "isRegistered": true
}]

Si prenda ora in considerazione il caso in cui fosse necessario modificare la formattazione dell'output JSON in una forma differente.Now consider the case where we need to reformat the JSON output in a different shape. Questa query proietta un nuovo oggetto JSON con due campi selezionati, Name e City, quando la città in cui si trova l'indirizzo ha lo stesso nome dello stato.This query projects a new JSON object with two selected fields, Name and City, when the address' city has the same name as the state. In questo caso, "NY, NY" corrispondono.In this case, "NY, NY" matches.

QueryQuery

SELECT {"Name":f.id, "City":f.address.city} AS Family 
FROM Families f 
WHERE f.address.city = f.address.state

RisultatiResults

[{
    "Family": {
        "Name": "WakefieldFamily", 
        "City": "NY"
    }
}]

La query successiva restituisce i nomi di elementi figlio specificati nella famiglia con ID corrispondente a WakefieldFamily ordinato in base alla città di residenza.The next query returns all the given names of children in the family whose id matches WakefieldFamily ordered by the city of residence.

QueryQuery

SELECT c.givenName 
FROM Families f 
JOIN c IN f.children 
WHERE f.id = 'WakefieldFamily'
ORDER BY f.address.city ASC

RisultatiResults

[
  { "givenName": "Jesse" }, 
  { "givenName": "Lisa"}
]

È opportuno prestare attenzione ad alcuni aspetti salienti del linguaggio di query di Cosmos DB attraverso gli esempi finora esaminati:We would like to draw attention to a few noteworthy aspects of the Cosmos DB query language through the examples we've seen so far:

  • Poiché l'API SQL di DocumentDB elabora i valori JSON, deve gestire entità con struttura ad albero invece di righe e colonne.Since DocumentDB API SQL works on JSON values, it deals with tree shaped entities instead of rows and columns. Di conseguenza, il linguaggio consente di fare riferimento ai nodi dell'albero a qualsiasi profondità arbitraria, ad esempio Node1.Node2.Node3…..Nodem, in modo analogo al linguaggio SQL relazionale con il riferimento in due parti di <table>.<column>.Therefore, the language lets you refer to nodes of the tree at any arbitrary depth, like Node1.Node2.Node3…..Nodem, similar to relational SQL referring to the two part reference of <table>.<column>.
  • Il linguaggio strutturato di interrogazione funziona con dati senza schema.The structured query language works with schema-less data. perciò il sistema di tipi deve essere associato in modo dinamico.Therefore, the type system needs to be bound dynamically. La stessa espressione potrebbe produrre tipi differenti su documenti differenti.The same expression could yield different types on different documents. Il risultato di una query è un valore JSON valido, ma non è garantito che appartenga a uno schema fisso.The result of a query is a valid JSON value, but is not guaranteed to be of a fixed schema.
  • Cosmos DB supporta solo i documenti JSON completi.Cosmos DB only supports strict JSON documents. Ciò significa che il sistema di tipi e le espressioni sono limitati all'interazione esclusiva con i tipi JSON.This means the type system and expressions are restricted to deal only with JSON types. Per altri dettagli, vedere le specifiche JSON.Refer to the JSON specification for more details.
  • Una raccolta di Cosmos DB è un contenitore senza schema dei documenti JSON.A Cosmos DB collection is a schema-free container of JSON documents. Le relazioni nelle entità di dati all'interno e tra i documenti in una raccolta vengono implicitamente acquisiti dal contenitore e non dalle relazioni chiave primaria e chiave esterna.The relations in data entities within and across documents in a collection are implicitly captured by containment and not by primary key and foreign key relations. È un aspetto importante da sottolineare alla luce dei join tra documenti, descritti più avanti in questo articolo.This is an important aspect worth pointing out in light of the intra-document joins discussed later in this article.

Indicizzatore di Cosmos DBCosmos DB indexing

Prima di addentrarsi nella sintassi dell'API SQL di DocumentDB, vale la pena esplorare la progettazione dell'indicizzazione di Cosmos DB.Before we get into the DocumentDB API SQL syntax, it is worth exploring the indexing design in Cosmos DB.

Lo scopo degli indici di database è gestire le query in varie forme con un consumo di risorse ridotto al minimo (ad esempio CPU, input/output), offrendo al contempo una buona velocità effettiva e basse latenze.The purpose of database indexes is to serve queries in their various forms and shapes with minimum resource consumption (like CPU and input/output) while providing good throughput and low latency. Spesso, la scelta dell'indice corretto per l'interrogazione di un database richiede una lunga pianificazione e sperimentazione.Often, the choice of the right index for querying a database requires much planning and experimentation. Questo approccio costituisce una sfida per i database senza schema, in cui i dati non si conformano a un rigido schema ed evolvono rapidamente.This approach poses a challenge for schema-less databases where the data doesn’t conform to a strict schema and evolves rapidly.

Di conseguenza, durante la progettazione del sottosistema di indicizzazione di Cosmos DB sono stati fissati gli obiettivi seguenti:Therefore, when we designed the Cosmos DB indexing subsystem, we set the following goals:

  • Indicizzare i documenti senza schema: il sottosistema di indicizzazione non richiede alcuna informazione sullo schema o supposizioni sullo schema dei documenti.Index documents without requiring schema: The indexing subsystem does not require any schema information or make any assumptions about schema of the documents.
  • Supporto di query relazionali e gerarchiche efficienti e complesse: l'indice supporta il linguaggio di query Cosmos DB in modo efficiente, incluso il supporto per le proiezioni relazionali e gerarchiche.Support for efficient, rich hierarchical, and relational queries: The index supports the Cosmos DB query language efficiently, including support for hierarchical and relational projections.
  • Supporto per le query coerente sia un volume di scritture sostenuta: per la scrittura ad alta velocità effettiva dei carichi di lavoro con query coerenti, l'indice viene aggiornato in modo incrementale, in modo efficiente e in linea con un volume sostenuto delle operazioni di scrittura.Support for consistent queries in face of a sustained volume of writes: For high write throughput workloads with consistent queries, the index is updated incrementally, efficiently, and online in the face of a sustained volume of writes. L'aggiornamento coerente dell'indice è fondamentale per la gestione delle query secondo il livello di coerenza con cui l'utente ha configurato il servizio documenti.The consistent index update is crucial to serve the queries at the consistency level in which the user configured the document service.
  • Supporto per multi-tenancy: dato il modello basato sulla prenotazione per la governance delle risorse tra tenant, gli aggiornamenti dell'indice vengono eseguiti mantenendosi nel budget delle risorse di sistema (CPU, memoria e operazioni di input/output al secondo) allocate per ogni replica.Support for multi-tenancy: Given the reservation-based model for resource governance across tenants, index updates are performed within the budget of system resources (CPU, memory, and input/output operations per second) allocated per replica.
  • Per conseguire l'efficienza dei costi, le risorse di archiviazione su disco dell'indice sono vincolate e prevedibili.Storage efficiency: For cost effectiveness, the on-disk storage overhead of the index is bounded and predictable. Questo è fondamentale perché Cosmos DB consente allo sviluppatore di accettare compromessi basati sul costo tra spese relative all'indice e prestazioni delle query.This is crucial because Cosmos DB allows the developer to make cost-based tradeoffs between index overhead in relation to the query performance.

Per informazioni su come configurare i criteri di indicizzazione per una raccolta, vedere gli esempi relativi a Azure Cosmos DB su MSDN.Refer to the Azure Cosmos DB samples on MSDN for samples showing how to configure the indexing policy for a collection. Verrà ora analizzata più dettagliatamente la sintassi SQL di Azure Cosmos DB.Let’s now get into the details of the Azure Cosmos DB SQL syntax.

Elementi di base di una query SQL di Cosmos DBBasics of an Azure Cosmos DB SQL query

Ogni query consiste in una clausola SELECT e clausole FROM e WHERE facoltative in base agli standard ANSI-SQL.Every query consists of a SELECT clause and optional FROM and WHERE clauses per ANSI-SQL standards. In genere, l'origine nella clausola FROM per ogni query viene enumerata,Typically, for each query, the source in the FROM clause is enumerated. quindi il filtro nella clausola WHERE viene applicato all'origine per recuperare un sottoinsieme di documenti JSON.Then the filter in the WHERE clause is applied on the source to retrieve a subset of JSON documents. Infine, viene usata la clausola SELECT per proiettare i valori JSON richiesti nell'elenco selezionato.Finally, the SELECT clause is used to project the requested JSON values in the select list.

SELECT <select_list> 
[FROM <from_specification>] 
[WHERE <filter_condition>]
[ORDER BY <sort_specification]    

Clausola FROMFROM clause

La clausola FROM <from_specification> è facoltativa, a meno che l'origine non sia filtrata o proiettata più avanti nella query.The FROM <from_specification> clause is optional unless the source is filtered or projected later in the query. Lo scopo di questa query è specificare l'origine dati in base alla quale deve operare la query.The purpose of this clause is to specify the data source upon which the query must operate. Comunemente, l'origine è rappresentata dall'intera raccolta, ma è possibile specificare piuttosto un sottoinsieme della raccolta.Commonly the whole collection is the source, but one can specify a subset of the collection instead.

Una query come SELECT * FROM Families indica che l'intera raccolta Families è il database di origine in base al quale eseguire l'enumerazione.A query like SELECT * FROM Families indicates that the entire Families collection is the source over which to enumerate. Invece di usare il nome della raccolta, è possibile usare uno speciale identificatore ROOT per rappresentare la raccolta.A special identifier ROOT can be used to represent the collection instead of using the collection name. L'elenco seguente include le regole applicate per ogni query:The following list contains the rules that are enforced per query:

  • È possibile effettuare l'aliasing della raccolta, come in SELECT f.id FROM Families AS f o semplicemente in SELECT f.id FROM Families f.The collection can be aliased, such as SELECT f.id FROM Families AS f or simply SELECT f.id FROM Families f. Qui f è l'equivalente di Families.Here f is the equivalent of Families. AS è una parola chiave facoltativa per eseguire l'aliasing dell'identificatore.AS is an optional keyword to alias the identifier.
  • Una volta eseguito l'aliasing, non sarà più possibile associare l'origine iniziale.Once aliased, the original source cannot be bound. Ad esempio, la sintassi di SELECT Families.id FROM Families f non è valida perché non è più possibile risolvere l'identificatore "Families".For example, SELECT Families.id FROM Families f is syntactically invalid since the identifier "Families" cannot be resolved anymore.
  • Tutte le proprietà a cui è necessario fare riferimento devono essere complete.All properties that need to be referenced must be fully qualified. In assenza di una rigorosa aderenza allo schema, ciò viene applicato per evitare eventuali associazioni ambigue.In the absence of strict schema adherence, this is enforced to avoid any ambiguous bindings. Di conseguenza, la sintassi di SELECT id FROM Families f non è valida perché la proprietà id non è associata.Therefore, SELECT id FROM Families f is syntactically invalid since the property id is not bound.

Documenti secondariSubdocuments

È anche possibile ridurre il database di origine a un sottoinsieme di dimensioni inferiori.The source can also be reduced to a smaller subset. Ad esempio, per enumerare un solo sottoalbero in ogni documento, la sottoradice può quindi diventare l'origine, come nell'esempio seguente:For instance, to enumerating only a subtree in each document, the subroot could then become the source, as shown in the following example:

QueryQuery

SELECT * 
FROM Families.children

RisultatiResults

[
  [
    {
        "firstName": "Henriette Thaulow",
        "gender": "female",
        "grade": 5,
        "pets": [
          {
              "givenName": "Fluffy"
          }
        ]
    }
  ],
  [
    {
        "familyName": "Merriam",
        "givenName": "Jesse",
        "gender": "female",
        "grade": 1
    },
    {
        "familyName": "Miller",
        "givenName": "Lisa",
        "gender": "female",
        "grade": 8
    }
  ]
]

Mentre nell'esempio precedente viene usata una matrice come origine, si potrebbe usare anche un oggetto come origine, che è quanto mostrato nell'esempio seguente: qualsiasi valore JSON valido (non indefinito) che può essere trovato nell'origine viene considerato per l'inclusione nel risultato della query.While the above example used an array as the source, an object could also be used as the source, which is what's shown in the following example: Any valid JSON value (not undefined) that can be found in the source is considered for inclusion in the result of the query. Se alcune famiglie non hanno un valore address.state vengono escluse dal risultato della query.If some families don’t have an address.state value, they are excluded in the query result.

QueryQuery

SELECT * 
FROM Families.address.state

RisultatiResults

[
  "WA", 
  "NY"
]

Clausola WHEREWHERE clause

La clausola WHERE (WHERE <filter_condition>) è facoltativa.The WHERE clause (WHERE <filter_condition>) is optional. e specifica la condizione (o le condizioni) che i documenti JSON forniti dall'origine devono soddisfare per essere inclusi come parte del risultato.It specifies the condition(s) that the JSON documents provided by the source must satisfy in order to be included as part of the result. Per essere considerato per il risultato, qualsiasi documento JSON deve valutare le condizioni specificate come "true".Any JSON document must evaluate the specified conditions to "true" to be considered for the result. La clausola WHERE viene usata dal livello di indice allo scopo di determinare il sottoinsieme più piccolo in assoluto di documenti di origine che possono fare parte del risultato.The WHERE clause is used by the index layer in order to determine the absolute smallest subset of source documents that can be part of the result.

La query seguente richiede documenti che contengono una proprietà nome il cui valore è AndersenFamily.The following query requests documents that contain a name property whose value is AndersenFamily. Qualsiasi altro documento che non contiene una proprietà nome o il cui valore non corrisponde a AndersenFamily verrà escluso.Any other document that does not have a name property, or where the value does not match AndersenFamily is excluded.

QueryQuery

SELECT f.address
FROM Families f 
WHERE f.id = "AndersenFamily"

RisultatiResults

[{
  "address": {
    "state": "WA", 
    "county": "King", 
    "city": "seattle"
  }
}]

Nell'esempio precedente è stata illustrata una semplice query di uguaglianza.The previous example showed a simple equality query. L'API SQL di DocumentDB supporta anche una varietà di espressioni scalari.DocumentDB API SQL also supports a variety of scalar expressions. Quelle di uso più comune sono le espressioni binarie e unarie.The most commonly used are binary and unary expressions. Anche i riferimenti di proprietà dell'oggetto JSON sono espressioni valide.Property references from the source JSON object are also valid expressions.

Gli operatori binari seguenti sono attualmente supportati e possono essere usati nelle query come illustrato negli esempi riportati di seguito:The following binary operators are currently supported and can be used in queries as shown in the following examples:





AritmeticoArithmetic+,-,,/,%+,-,,/,%
Bit per bitBitwise|, &, ^, <<, >>, >>> (spostamento a destra riempimento zero)|, &, ^, <<, >>, >>> (zero-fill right shift)
LogicoLogical AND, OR, NOTAND, OR, NOT
ConfrontoComparison=, !=, <, >, <=, >=, <>=, !=, <, >, <=, >=, <>
StringString|| (concatenazione)|| (concatenate)

Saranno ora prese in esame alcune query che usano gli operatori binari.Let’s take a look at some queries using binary operators.

SELECT * 
FROM Families.children[0] c
WHERE c.grade % 2 = 1     -- matching grades == 5, 1

SELECT * 
FROM Families.children[0] c
WHERE c.grade ^ 4 = 1    -- matching grades == 5

SELECT *
FROM Families.children[0] c
WHERE c.grade >= 5     -- matching grades == 5

Sono supportati anche gli operatori unari +,-, ~ e NOT, che possono essere usati all'interno delle query come illustrato di seguito:The unary operators +,-, ~ and NOT are also supported, and can be used inside queries as shown in the following example:

SELECT *
FROM Families.children[0] c
WHERE NOT(c.grade = 5)  -- matching grades == 1

SELECT *
FROM Families.children[0] c
WHERE (-c.grade = -5)  -- matching grades == 5

Oltre agli operatori binari e unari, sono consentiti anche i riferimenti di proprietà.In addition to binary and unary operators, property references are also allowed. Ad esempio, SELECT * FROM Families f WHERE f.isRegistered restituirebbe i documenti JSON contenenti la proprietà isRegistered dove il valore della proprietà è uguale al valore JSON true.For example, SELECT * FROM Families f WHERE f.isRegistered returns the JSON document containing the property isRegistered where the property's value is equal to the JSON true value. Qualsiasi altro valore (false, null, Undefined, <number>, <string>, <object>, <array> e così via) comporta l'esclusione del documento di origine dai risultati.Any other values (false, null, Undefined, <number>, <string>, <object>, <array>, etc.) leads to the source document being excluded from the result.

Operatori di confronto e uguaglianzaEquality and comparison operators

La tabella seguente illustra il risultato dei confronti di uguaglianza nell'API SQL di DocumentDB tra due tipi JSON qualsiasi.The following table shows the result of equality comparisons in DocumentDB API SQL between any two JSON types.

Op Op Undefined Undefined Null Null Boolean Boolean Number Number String String Object Object Array Array
Undefined Undefined UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined
Null Null UndefinedUndefined OK OK UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined
Boolean Boolean UndefinedUndefined UndefinedUndefined OK OK UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined
Number Number UndefinedUndefined UndefinedUndefined UndefinedUndefined OK OK UndefinedUndefined UndefinedUndefined UndefinedUndefined
String String UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined OK OK UndefinedUndefined UndefinedUndefined
Object Object UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined OK OK UndefinedUndefined
Array Array UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined UndefinedUndefined OK OK

Per gli altri operatori di confronto, ad esempio >, >=, !=, < e <=, si applicano le regole seguenti:For other comparison operators such as >, >=, !=, < and <=, the following rules apply:

  • Confronto tra risultati dei tipi in Undefined.Comparison across types results in Undefined.
  • Confronto tra i risultati di due oggetti o due matrici in Undefined.Comparison between two objects or two arrays results in Undefined.

Se il risultato dell'espressione scalare nel filtro è Undefined, il documento corrispondente non verrebbe incluso nel risultato, perché Undefined non è logicamente uguale a "true".If the result of the scalar expression in the filter is Undefined, the corresponding document would not be included in the result, since Undefined doesn't logically equate to "true".

Parola chiave BETWEENBETWEEN keyword

È possibile usare anche la parola chiave BETWEEN per esprimere query su intervalli di valori come in SQL ANSI.You can also use the BETWEEN keyword to express queries against ranges of values like in ANSI SQL. La parola BETWEEN può essere utilizzata con stringhe o numeri.BETWEEN can be used against strings or numbers.

Ad esempio, questa query restituisce tutti i documenti della famiglia in cui la classe frequentata dal primo figlio sia compresa tra 1 e 5 (inclusi).For example, this query returns all family documents in which the first child's grade is between 1-5 (both inclusive).

SELECT *
FROM Families.children[0] c
WHERE c.grade BETWEEN 1 AND 5

A differenza di SQL ANSI, è possibile usare la clausola BETWEEN anche nella clausola FROM, come nell'esempio seguente.Unlike in ANSI-SQL, you can also use the BETWEEN clause in the FROM clause like in the following example.

SELECT (c.grade BETWEEN 0 AND 10)
FROM Families.children[0] c

Per accelerare l'esecuzione della query, creare un criterio di indicizzazione che usa un tipo di indice di intervallo su qualsiasi proprietà/percorso numerico filtrato nella clausola BETWEEN.For faster query execution times, remember to create an indexing policy that uses a range index type against any numeric properties/paths that are filtered in the BETWEEN clause.

La differenza principale tra l'uso di BETWEEN nell'API di DocumentDB e ANSI SQL consiste nel fatto che è possibile esprimere le query di intervallo su proprietà di tipo misto. Ad esempio, "grade" può essere un numero (5) in alcuni documenti e stringhe in altri ("grade4").The main difference between using BETWEEN in DocumentDB API and ANSI SQL is that you can express range queries against properties of mixed types – for example, you might have "grade" be a number (5) in some documents and strings in others ("grade4"). In questi casi, come in JavaScript, un confronto tra due tipi diversi restituisce un risultato "undefined" e il documento viene ignorato.In these cases, like in JavaScript, a comparison between two different types results in "undefined", and the document will be skipped.

Operatori logici (AND, OR e NOT)Logical (AND, OR and NOT) operators

Gli operatori logici funzionano con valori booleani.Logical operators operate on Boolean values. Le tabelle di veridicità logica per questi operatori sono illustrate di seguito.The logical truth tables for these operators are shown in the following tables.

OPPUREOR TrueTrue FalseFalse UndefinedUndefined
TrueTrue TrueTrue TrueTrue TrueTrue
FalseFalse TrueTrue FalseFalse UndefinedUndefined
UndefinedUndefined TrueTrue UndefinedUndefined UndefinedUndefined
ANDAND TrueTrue FalseFalse UndefinedUndefined
TrueTrue TrueTrue FalseFalse UndefinedUndefined
FalseFalse FalseFalse FalseFalse FalseFalse
UndefinedUndefined UndefinedUndefined FalseFalse UndefinedUndefined
NOTNOT
TrueTrue FalseFalse
FalseFalse TrueTrue
UndefinedUndefined UndefinedUndefined

Parola chiave ININ keyword

La parola chiave IN consente di controllare se un valore specificato corrisponde a qualsiasi valore in un elenco.The IN keyword can be used to check whether a specified value matches any value in a list. Ad esempio, questa query restituisce tutti i documenti famiglia dove l'id è uno dei "WakefieldFamily" o "AndersenFamily".For example, this query returns all family documents where the id is one of "WakefieldFamily" or "AndersenFamily".

SELECT *
FROM Families 
WHERE Families.id IN ('AndersenFamily', 'WakefieldFamily')

In questo esempio restituisce tutti i documenti in cui lo stato è uno dei valori specificati.This example returns all documents where the state is any of the specified values.

SELECT *
FROM Families 
WHERE Families.address.state IN ("NY", "WA", "CA", "PA", "OH", "OR", "MI", "WI", "MN", "FL")

Operatori Ternary (?) e Coalesce (??)Ternary (?) and Coalesce (??) operators

Gli operatori Ternary e Coalesce possono essere usati per compilare espressioni condizionali, analogamente ai linguaggi di programmazione più diffusi come C# e JavaScript.The Ternary and Coalesce operators can be used to build conditional expressions, similar to popular programming languages like C# and JavaScript.

L'operatore Ternary (?) può essere molto comodo quando si costruiscono rapidamente nuove proprietà JSON.The Ternary (?) operator can be very handy when constructing new JSON properties on the fly. Ad esempio, ora è possibile scrivere query per classificare i livelli di istruzione in forma leggibile, ad esempio principiante/intermedio/avanzati, come mostrato di seguito.For example, now you can write queries to classify the class levels into a human readable form like Beginner/Intermediate/Advanced as shown below.

 SELECT (c.grade < 5)? "elementary": "other" AS gradeLevel 
 FROM Families.children[0] c

È anche possibile annidare le chiamate all'operatore come nella query seguente.You can also nest the calls to the operator like in the query below.

SELECT (c.grade < 5)? "elementary": ((c.grade < 9)? "junior": "high")  AS gradeLevel 
FROM Families.children[0] c

Come con altri operatori di query, se le proprietà cui viene fatto riferimento nell'espressione condizionale non sono presenti in alcun documento o se i tipi confrontati sono diversi, tali documenti vengono esclusi dai risultati della query.As with other query operators, if the referenced properties in the conditional expression are missing in any document, or if the types being compared are different, then those documents are excluded in the query results.

L'operatore Coalesce (??) può essere usato per verificare se una proprietà è presenteThe Coalesce (??) operator can be used to efficiently check for the presence of a property (a.k.a. (definita) in un documento.is defined) in a document. Questo risulta utile per le query su dati semistrutturati o di tipo mistoThis is useful when querying against semi-structured or data of mixed types. Ad esempio, questa query restituisce il valore "lastName" se è presente oppure il valore "surname" se non è presente.For example, this query returns the "lastName" if present, or the "surname" if it isn't present.

SELECT f.lastName ?? f.surname AS familyName
FROM Families f

Funzione di accesso della proprietà di delimitazioneQuoted property accessor

È anche possibile accedere alle proprietà mediante l'operatore della proprietà di delimitazione [].You can also access properties using the quoted property operator []. Ad esempio, la sintassi di SELECT c.grade and SELECT c["grade"] sono equivalenti.For example, SELECT c.grade and SELECT c["grade"] are equivalent. Questa sintassi risulta utile quando occorre usare i caratteri di escape per una proprietà che contiene spazi, caratteri speciali o condivide lo stesso nome di una parola chiave SQL o una parola riservata.This syntax is useful when you need to escape a property that contains spaces, special characters, or happens to share the same name as a SQL keyword or reserved word.

SELECT f["lastName"]
FROM Families f
WHERE f["id"] = "AndersenFamily"

Clausola SELECTSELECT clause

La clausola SELECT (SELECT <select_list>) è obbligatoria e specifica quali valori vengono recuperati dalla query, proprio come in ANSI-SQL.The SELECT clause (SELECT <select_list>) is mandatory and specifies what values are retrieved from the query, just like in ANSI-SQL. Il sottoinsieme filtrato dai documenti di origine viene passato alla fase di proiezione, in cui vengono recuperati i valori JSON specificati viene costruito un nuovo oggetto JSON, per ogni input passato ad esso.The subset that's been filtered on top of the source documents are passed onto the projection phase, where the specified JSON values are retrieved and a new JSON object is constructed, for each input passed onto it.

L'esempio seguente illustra una tipica query SELECT.The following example shows a typical SELECT query.

QueryQuery

SELECT f.address
FROM Families f 
WHERE f.id = "AndersenFamily"

RisultatiResults

[{
  "address": {
    "state": "WA", 
    "county": "King", 
    "city": "seattle"
  }
}]

Proprietà annidateNested properties

Nell'esempio seguente vengono proiettate due proprietà annidate f.address.state and f.address.city.In the following example, we are projecting two nested properties f.address.state and f.address.city.

QueryQuery

SELECT f.address.state, f.address.city
FROM Families f 
WHERE f.id = "AndersenFamily"

RisultatiResults

[{
  "state": "WA", 
  "city": "seattle"
}]

La proiezione supporta anche le espressioni JSON, come illustrato nell'esempio seguente:Projection also supports JSON expressions as shown in the following example:

QueryQuery

SELECT { "state": f.address.state, "city": f.address.city, "name": f.id }
FROM Families f 
WHERE f.id = "AndersenFamily"

RisultatiResults

[{
  "$1": {
    "state": "WA", 
    "city": "seattle", 
    "name": "AndersenFamily"
  }
}]

Verrà ora esaminato il ruolo di $1 .Let's look at the role of $1 here. La clausola SELECT deve creare un oggetto JSON e, poiché non è stata fornita alcuna chiave, verranno usati i nomi di variabile di argomento implicita che iniziano per $1.The SELECT clause needs to create a JSON object and since no key is provided, we use implicit argument variable names starting with $1. Ad esempio, questa query restituisce due variabili di argomento implicite, etichettate $1 and $2.For example, this query returns two implicit argument variables, labeled $1 and $2.

QueryQuery

SELECT { "state": f.address.state, "city": f.address.city }, 
       { "name": f.id }
FROM Families f 
WHERE f.id = "AndersenFamily"

RisultatiResults

[{
  "$1": {
    "state": "WA", 
    "city": "seattle"
  }, 
  "$2": {
    "name": "AndersenFamily"
  }
}]

AliasingAliasing

L'esempio precedente verrà ora esteso con l'aliasing esplicito dei valori.Now let's extend the example above with explicit aliasing of values. AS è la parola chiave usata per l'aliasing.AS is the keyword used for aliasing. È facoltativo, come è possibile vedere durante la proiezione del secondo valore come NameInfo.It's optional as shown while projecting the second value as NameInfo.

Nel caso in cui una query avesse due proprietà con lo stesso nome, è necessario usare l'aliasing per rinominare una o entrambe le proprietà, in modo da evitare ambiguità nel risultato proiettato.In case a query has two properties with the same name, aliasing must be used to rename one or both of the properties so that they are disambiguated in the projected result.

QueryQuery

SELECT 
       { "state": f.address.state, "city": f.address.city } AS AddressInfo, 
       { "name": f.id } NameInfo
FROM Families f 
WHERE f.id = "AndersenFamily"

RisultatiResults

[{
  "AddressInfo": {
    "state": "WA", 
    "city": "seattle"
  }, 
  "NameInfo": {
    "name": "AndersenFamily"
  }
}]

Espressioni scalariScalar expressions

Oltre ai riferimenti di proprietà, la clausola SELECT supporta anche le espressioni scalari, ad esempio le costanti, le espressioni aritmetiche, le espressioni logiche e così via. Ad esempio, ecco una semplice query "Hello World".In addition to property references, the SELECT clause also supports scalar expressions like constants, arithmetic expressions, logical expressions, etc. For example, here's a simple "Hello World" query.

QueryQuery

SELECT "Hello World"

RisultatiResults

[{
  "$1": "Hello World"
}]

Di seguito è presentato un esempio più complesso che usa un'espressione scalare.Here's a more complex example that uses a scalar expression.

QueryQuery

SELECT ((2 + 11 % 7)-2)/3    

RisultatiResults

[{
  "$1": 1.33333
}]

Nell'esempio seguente, il risultato dell'espressione scalare è un valore booleano.In the following example, the result of the scalar expression is a Boolean.

QueryQuery

SELECT f.address.city = f.address.state AS AreFromSameCityState
FROM Families f    

RisultatiResults

[
  {
    "AreFromSameCityState": false
  }, 
  {
    "AreFromSameCityState": true
  }
]

Creazione di oggetti e matriciObject and array creation

Un'altra funzione fondamentale dell'API SQL di DocumentDB è la creazione di matrici/oggetti.Another key feature of DocumentDB API SQL is array/object creation. Nell'esempio precedente si è osservato che è stato creato un nuovo oggetto JSON.In the previous example, note that we created a new JSON object. In modo analogo, è possibile creare matrici, come illustrato negli esempi seguenti:Similarly, one can also construct arrays as shown in the following examples:

QueryQuery

SELECT [f.address.city, f.address.state] AS CityState 
FROM Families f    

RisultatiResults

[
  {
    "CityState": [
      "seattle", 
      "WA"
    ]
  }, 
  {
    "CityState": [
      "NY", 
      "NY"
    ]
  }
]

Parola chiave VALUEVALUE keyword

La parola chiave VALUE consente di restituire un valore JSON.The VALUE keyword provides a way to return JSON value. Ad esempio, la query mostrata di seguito restituisce l'espressione scalare "Hello World" invece di {$1: "Hello World"}.For example, the query shown below returns the scalar "Hello World" instead of {$1: "Hello World"}.

QueryQuery

SELECT VALUE "Hello World"

RisultatiResults

[
  "Hello World"
]

La query seguente restituisce il valore JSON senza l'etichetta "address" nei risultati.The following query returns the JSON value without the "address" label in the results.

QueryQuery

SELECT VALUE f.address
FROM Families f    

RisultatiResults

[
  {
    "state": "WA", 
    "county": "King", 
    "city": "seattle"
  }, 
  {
    "state": "NY", 
    "county": "Manhattan", 
    "city": "NY"
  }
]

L'esempio seguente estende questo risultato mostrando come restituire valori primitivi JSON (il livello foglia dell'albero JSON).The following example extends this to show how to return JSON primitive values (the leaf level of the JSON tree).

QueryQuery

SELECT VALUE f.address.state
FROM Families f    

RisultatiResults

[
  "WA",
  "NY"
]

Operatore Operator

L'operatore speciale () è supportato per proiettare il documento così com'è.The special operator () is supported to project the document as-is. Quando usato, deve essere l'unico campo proiettato.When used, it must be the only projected field. Benché una query come SELECT * FROM Families f sia valida, SELECT VALUE * FROM Families f e SELECT *, f.id FROM Families f non lo sono.While a query like SELECT * FROM Families f is valid, SELECT VALUE * FROM Families f and SELECT *, f.id FROM Families f are not valid.

QueryQuery

SELECT * 
FROM Families f 
WHERE f.id = "AndersenFamily"

RisultatiResults

[{
    "id": "AndersenFamily",
    "lastName": "Andersen",
    "parents": [
       { "firstName": "Thomas" },
       { "firstName": "Mary Kay"}
    ],
    "children": [
       {
           "firstName": "Henriette Thaulow", "gender": "female", "grade": 5,
           "pets": [{ "givenName": "Fluffy" }]
       }
    ],
    "address": { "state": "WA", "county": "King", "city": "seattle" },
    "creationDate": 1431620472,
    "isRegistered": true
}]

Operatore TOPTOP Operator

La parola chiave TOP può essere usata per limitare il numero di valori restituiti da una query.The TOP keyword can be used to limit the number of values from a query. Se si usa TOP in combinazione con la clausola ORDER BY, il set di risultati è limitato al primo numero N di valori ordinati. In caso contrario, restituisce il primo numero N di risultati in un ordine non definito.When TOP is used in conjunction with the ORDER BY clause, the result set is limited to the first N number of ordered values; otherwise, it returns the first N number of results in an undefined order. Come procedura consigliata, in un'istruzione SELECT, usare sempre una clausola ORDER BY con la clausola TOP.As a best practice, in a SELECT statement, always use an ORDER BY clause with the TOP clause. Questo è l'unico modo per indicare in modo prevedibile le righe interessate dalla clausola TOP.This is the only way to predictably indicate which rows are affected by TOP.

QueryQuery

SELECT TOP 1 * 
FROM Families f 

RisultatiResults

[{
    "id": "AndersenFamily",
    "lastName": "Andersen",
    "parents": [
       { "firstName": "Thomas" },
       { "firstName": "Mary Kay"}
    ],
    "children": [
       {
           "firstName": "Henriette Thaulow", "gender": "female", "grade": 5,
           "pets": [{ "givenName": "Fluffy" }]
       }
    ],
    "address": { "state": "WA", "county": "King", "city": "seattle" },
    "creationDate": 1431620472,
    "isRegistered": true
}]

È possibile usare TOP con un valore costante (come illustrato in precedenza) o con un valore della variabile usando le query con parametri.TOP can be used with a constant value (as shown above) or with a variable value using parameterized queries. Per altre informazioni dettagliate, vedere le query con parametri seguenti.For more details, please see parameterized queries below.

Funzioni di aggregazioneAggregate Functions

È anche possibile eseguire le aggregazioni nella clausola SELECT.You can also perform aggregations in the SELECT clause. Le funzioni di aggregazione eseguono un calcolo su un set di valori e restituiscono un singolo valore.Aggregate functions perform a calculation on a set of values and return a single value. Ad esempio, la query seguente restituisce il numero di documenti della famiglia all'interno della raccolta.For example, the following query returns the count of family documents within the collection.

QueryQuery

SELECT COUNT(1) 
FROM Families f 

RisultatiResults

[{
    "$1": 2
}]

È anche possibile restituire il valore scalare della funzione di aggregazione tramite la parola chiave VALUE.You can also return the scalar value of the aggregate by using the VALUE keyword. Ad esempio, la query seguente restituisce il numero di valori come un singolo numero:For example, the following query returns the count of values as a single number:

QueryQuery

SELECT VALUE COUNT(1) 
FROM Families f 

RisultatiResults

[ 2 ]

È anche possibile eseguire aggregazioni combinate a filtri.You can also perform aggregates in combination with filters. Ad esempio, la query seguente restituisce il numero di documenti con un indirizzo nello Stato di Washington.For example, the following query returns the count of documents with the address in the state of Washington.

QueryQuery

SELECT VALUE COUNT(1) 
FROM Families f
WHERE f.address.state = "WA" 

RisultatiResults

[ 1 ]

La tabella seguente mostra l'elenco delle funzioni di aggregazione supportate nell'API di DocumentDB.The following table shows the list of supported aggregate functions in DocumentDB API. SUMe AVG vengono eseguite su valori numerici, mentre COUNT, MIN e MAX possono essere eseguite su numeri, stringhe, valori booleani e valori null.SUM and AVG are performed over numeric values, whereas COUNT, MIN, and MAX can be performed over numbers, strings, Booleans, and nulls.

UtilizzoUsage DescrizioneDescription
COUNTCOUNT Restituisce il numero di elementi nell'espressione.Returns the number of items in the expression.
SUMSUM Restituisce la somma dei valori nell'espressione.Returns the sum of all the values in the expression.
MINMIN Restituisce il valore minimo nell'espressione.Returns the minimum value in the expression.
MAXMAX Restituisce il valore massimo nell'espressione.Returns the maximum value in the expression.
MEDIAAVG Restituisce la media dei valori nell'espressione.Returns the average of the values in the expression.

Le aggregazioni possono essere eseguite anche sui risultati di un'iterazione della matrice.Aggregates can also be performed over the results of an array iteration. Per altre informazioni, vedere Array Iteration in Queries (Iterazione della matrice nelle query).For more information, see Array Iteration in Queries.

Nota

Tenere presente che quando si usa Esplora Query del portale di Azure, le query di aggregazione possono restituire risultati parzialmente aggregati su una pagina di query.When using the Azure portal's Query Explorer, note that aggregation queries may return the partially aggregated results over a query page. L'SDK genera un singolo valore cumulativo in tutte le pagine.The SDKs produces a single cumulative value across all pages.

Per eseguire query di aggregazione tramite codice, è necessario .NET SDK 1.12.0, .NET Core SDK 1.1.0 o SDK per Java 1.9.5 o versione successiva.In order to perform aggregation queries using code, you need .NET SDK 1.12.0, .NET Core SDK 1.1.0, or Java SDK 1.9.5 or above.

Clausola ORDER BYORDER BY clause

Come in SQL ANSI, è possibile includere una clausola Order By facoltativa durante l'esecuzione di query.Like in ANSI-SQL, you can include an optional Order By clause while querying. La clausola può includere un argomento ASC/DESC facoltativo per specificare l'ordine in cui i risultati devono essere recuperati.The clause can include an optional ASC/DESC argument to specify the order in which results must be retrieved.

Ad esempio, la query seguente recupera le famiglie in ordine di nome della città di residenza.For example, here's a query that retrieves families in order of the resident city's name.

QueryQuery

SELECT f.id, f.address.city
FROM Families f 
ORDER BY f.address.city

RisultatiResults

[
  {
    "id": "WakefieldFamily",
    "city": "NY"
  },
  {
    "id": "AndersenFamily",
    "city": "Seattle"    
  }
]

La query seguente recupera le famiglie in ordine di data di creazione, archiviata come numero che rappresenta il periodo, ovvero il tempo trascorso dall'1 gennaio 1970 in secondi.And here's a query that retrieves families in order of creation date, which is stored as a number representing the epoch time, i.e, elapsed time since Jan 1, 1970 in seconds.

QueryQuery

SELECT f.id, f.creationDate
FROM Families f 
ORDER BY f.creationDate DESC

RisultatiResults

[
  {
    "id": "WakefieldFamily",
    "creationDate": 1431620462
  },
  {
    "id": "AndersenFamily",
    "creationDate": 1431620472    
  }
]

Concetti avanzati relativi ai database e alle query SQLAdvanced database concepts and SQL queries

IterazioneIteration

Nell'API SQL di DocumentDB è stato aggiunto un nuovo costrutto tramite la parola chiave IN per fornire supporto all'iterazione nelle matrici JSON.A new construct was added via the IN keyword in DocumentDB API SQL to provide support for iterating over JSON arrays. L'origine FROM fornisce supporto per l'iterazione.The FROM source provides support for iteration. Esaminare l'esempio seguente:Let's start with the following example:

QueryQuery

SELECT * 
FROM Families.children

RisultatiResults

[
  [
    {
      "firstName": "Henriette Thaulow", 
      "gender": "female", 
      "grade": 5, 
      "pets": [{ "givenName": "Fluffy"}]
    }
  ], 
  [
    {
        "familyName": "Merriam", 
        "givenName": "Jesse", 
        "gender": "female", 
        "grade": 1
    }, 
    {
        "familyName": "Miller", 
        "givenName": "Lisa", 
        "gender": "female", 
        "grade": 8
    }
  ]
]

Esaminare ora un'altra query che esegue l'iterazione sui figli nella raccolta.Now let's look at another query that performs iteration over children in the collection. Notare la differenza nella matrice di output.Note the difference in the output array. Questo esempio suddivide children e converte i risultati in un'unica matrice.This example splits children and flattens the results into a single array.

QueryQuery

SELECT * 
FROM c IN Families.children

RisultatiResults

[
  {
      "firstName": "Henriette Thaulow",
      "gender": "female",
      "grade": 5,
      "pets": [{ "givenName": "Fluffy" }]
  },
  {
      "familyName": "Merriam",
      "givenName": "Jesse",
      "gender": "female",
      "grade": 1
  },
  {
      "familyName": "Miller",
      "givenName": "Lisa",
      "gender": "female",
      "grade": 8
  }
]

Può essere usato per filtrare ulteriormente ciascuna voce individuale della matrice, come illustrato nell'esempio seguente:This can be further used to filter on each individual entry of the array as shown in the following example:

QueryQuery

SELECT c.givenName
FROM c IN Families.children
WHERE c.grade = 8

RisultatiResults

[{
  "givenName": "Lisa"
}]

È anche possibile eseguire l'aggregazione sul risultato dell'iterazione della matrice.You can also perform aggregation over the result of array iteration. Ad esempio, la query seguente conta il numero di figli in tutte le famiglie.For example, the following query counts the number of children among all families.

QueryQuery

SELECT COUNT(child) 
FROM child IN Families.children

RisultatiResults

[
  { 
    "$1": 3
  }
]

JoinJoins

In un database relazionale, la necessità creare un join tra tabelle è importante.In a relational database, the need to join across tables is important. È il corollario logico della progettazione di schemi normalizzati.It's the logical corollary to designing normalized schemas. Al contrario, l'API di DocumentDB gestisce un modello dati denormalizzato di documenti senza schema.Contrary to this, DocumentDB API deals with the denormalized data model of schema-free documents. È l'equivalente logico di un "self-join".This is the logical equivalent of a "self-join".

La sintassi supportata dal linguaggio è <from_source1> JOIN <from_source2> JOIN ... JOIN <from_sourceN>.The syntax that the language supports is <from_source1> JOIN <from_source2> JOIN ... JOIN <from_sourceN>. In generale, restituisce un set di tuple N (tupla con valori N).Overall, this returns a set of N-tuples (tuple with N values). Ogni tupla ha valori prodotti dall'iterazione di tutti gli alias della raccolta sui rispettivi set.Each tuple has values produced by iterating all collection aliases over their respective sets. In altri termini, si tratta del prodotto incrociato completo dei set che partecipano al join.In other words, this is a full cross product of the sets participating in the join.

Gli esempi seguenti illustrano il funzionamento della clausola JOIN.The following examples show how the JOIN clause works. Nell'esempio seguente, il risultato è vuoto perché il prodotto incrociato di ciascun documento dall'origine e un set vuoto è a sua volta vuoto.In the following example, the result is empty since the cross product of each document from source and an empty set is empty.

QueryQuery

SELECT f.id
FROM Families f
JOIN f.NonExistent

RisultatiResults

[{
}]

Nell'esempio seguente il join avviene tra la radice del documento e la sottoradice di children.In the following example, the join is between the document root and the children subroot. È un prodotto incrociato tra due oggetti JSON.It's a cross product between two JSON objects. Il fatto che i figli siano una matrice non è effettivo nel JOIN in quanto in questo esempio si ha a che fare con una singola radice che è anche la matrice dei figli.The fact that children is an array is not effective in the JOIN since we are dealing with a single root that is the children array. Di conseguenza, il risultato contiene solo due risultati, perché il prodotto incrociato di ogni documento con la matrice produce esattamente un solo documento.Hence the result contains only two results, since the cross product of each document with the array yields exactly only one document.

QueryQuery

SELECT f.id
FROM Families f
JOIN f.children

RisultatiResults

[
  {
    "id": "AndersenFamily"
  }, 
  {
    "id": "WakefieldFamily"
  }
]

L'esempio seguente illustra un join più convenzionale:The following example shows a more conventional join:

QueryQuery

SELECT f.id
FROM Families f
JOIN c IN f.children 

RisultatiResults

[
  {
    "id": "AndersenFamily"
  }, 
  {
    "id": "WakefieldFamily"
  }, 
  {
    "id": "WakefieldFamily"
  }
]

Per prima cosa occorre notare che il valore from_source della clausola JOIN è un iteratore.The first thing to note is that the from_source of the JOIN clause is an iterator. Pertanto il flusso in questo caso è il seguente:So, the flow in this case is as follows:

  • Espandere ciascun elemento figlio c nella matrice.Expand each child element c in the array.
  • Applicare un prodotto incrociato con la radice del documento f con ogni elemento figlio c che è stato convertito nel primo passaggio.Apply a cross product with the root of the document f with each child element c that was flattened in the first step.
  • Infine, proiettare solo la proprietà nome f dell'oggetto radice.Finally, project the root object f name property alone.

Il primo documento (AndersenFamily) contiene solo un elemento figlio, quindi il set di risultati contiene un singolo oggetto corrispondente a questo documento.The first document (AndersenFamily) contains only one child element, so the result set contains only a single object corresponding to this document. Il secondo documento (WakefieldFamily) contiene due elementi figlio.The second document (WakefieldFamily) contains two children. Quindi, il prodotto incrociato genera un oggetto separato per ogni figli, dando come risultato due oggetti, uno per ogni figlio corrispondente a questo documento.So, the cross product produces a separate object for each child, thereby resulting in two objects, one for each child corresponding to this document. I campi radice in entrambi i documenti sono uguali, proprio come ci si aspetterebbe in un prodotto incrociato.The root fields in both these documents are the same, just as you would expect in a cross product.

La vera utilità del JOIN consiste nel formare tuple dal prodotto incrociato in una forma che altrimenti sarebbe difficile proiettare.The real utility of the JOIN is to form tuples from the cross-product in a shape that's otherwise difficult to project. Come illustrato nell'esempio seguente, è possibile filtrare la combinazione di una tupla che consenta all'utente di scegliere una condizione soddisfatta dall'insieme delle tuple.Furthermore, as we see in the example below, you could filter on the combination of a tuple that lets' the user chose a condition satisfied by the tuples overall.

QueryQuery

SELECT 
    f.id AS familyName,
    c.givenName AS childGivenName,
    c.firstName AS childFirstName,
    p.givenName AS petName 
FROM Families f 
JOIN c IN f.children 
JOIN p IN c.pets

RisultatiResults

[
  {
    "familyName": "AndersenFamily", 
    "childFirstName": "Henriette Thaulow", 
    "petName": "Fluffy"
  }, 
  {
    "familyName": "WakefieldFamily", 
    "childGivenName": "Jesse", 
    "petName": "Goofy"
  }, 
  {
   "familyName": "WakefieldFamily", 
   "childGivenName": "Jesse", 
   "petName": "Shadow"
  }
]

Questo esempio è un'estensione naturale del precedente e illustra l'esecuzione di un doppio join.This example is a natural extension of the preceding example, and performs a double join. Il prodotto incrociato può quindi essere visualizzato come lo pseudo-codice seguente:So, the cross product can be viewed as the following pseudo-code:

for-each(Family f in Families)
{    
    for-each(Child c in f.children)
    {
        for-each(Pet p in c.pets)
        {
            return (Tuple(f.id AS familyName, 
              c.givenName AS childGivenName, 
              c.firstName AS childFirstName,
              p.givenName AS petName));
        }
    }
}

AndersenFamily ha un figlio che ha un animale domestico.AndersenFamily has one child who has one pet. Il prodotto incrociato genera dunque una riga (1*1*1) da questa famiglia.So, the cross product yields one row (1*1*1) from this family. Tuttavia, la famiglia WakefieldFamily ha due figli, ma un solo figlio, "Jesse", ha animali domestici.WakefieldFamily however has two children, but only one child "Jesse" has pets. Jesse ha però due animali domestici.Jesse has two pets though. il prodotto incrociato genera dunque 1*1*2 = 2 righe da questa famiglia.Hence the cross product yields 1*1*2 = 2 rows from this family.

Nell'esempio successivo è presente un filtro aggiuntivo su pet.In the next example, there is an additional filter on pet. In tal modo vengono escluse tutte le tuple laddove il nome dell'animale non è "Shadow".This excludes all the tuples where the pet name is not "Shadow". Notare che è possibile creare tuple da matrici, filtrare in base a uno qualsiasi degli elementi della tupla e proiettare qualsiasi combinazione degli elementi.Notice that we are able to build tuples from arrays, filter on any of the elements of the tuple, and project any combination of the elements.

QueryQuery

SELECT 
    f.id AS familyName,
    c.givenName AS childGivenName,
    c.firstName AS childFirstName,
    p.givenName AS petName 
FROM Families f 
JOIN c IN f.children 
JOIN p IN c.pets
WHERE p.givenName = "Shadow"

RisultatiResults

[
  {
   "familyName": "WakefieldFamily", 
   "childGivenName": "Jesse", 
   "petName": "Shadow"
  }
]

Integrazione JavaScriptJavaScript integration

Azure Cosmos DB offre un modello di programmazione per l'esecuzione di logica dell'applicazione basata su JavaScript direttamente nelle raccolte in termini di stored procedure e trigger.Azure Cosmos DB provides a programming model for executing JavaScript based application logic directly on the collections in terms of stored procedures and triggers. Ciò consente quanto segue:This allows for both:

  • Possibilità di eseguire query e operazioni CRUD transazionali con prestazioni elevate a fronte dei documenti in una raccolta grazie alla stretta integrazione del runtime JavaScript direttamente nel motore di database.Ability to do high-performance transactional CRUD operations and queries against documents in a collection by virtue of the deep integration of JavaScript runtime directly within the database engine.
  • Modellazione naturale del flusso di controllo, definizione dell'ambito delle variabili e assegnazione e integrazione di primitivi di gestione delle eccezioni con transazioni di database.A natural modeling of control flow, variable scoping, and assignment and integration of exception handling primitives with database transactions. Per altri dettagli sul supporto di Azure Cosmos DB per l'integrazione di JavaScript, vedere la documentazione relativa alla programmabilità lato server di JavaScript.For more details about Azure Cosmos DB support for JavaScript integration, please refer to the JavaScript server-side programmability documentation.

Funzioni definite dall'utente (UDF)User-Defined Functions (UDFs)

Oltre ai tipi già specificati in questo articolo, l'API SQL di DocumentDB offre il supporto per le funzioni definite dall'utente (UDF).Along with the types already defined in this article, DocumentDB API SQL provides support for User Defined Functions (UDF). In particolare, le UDF scalari sono supportate laddove gli sviluppatori possono passare zero o molti argomenti e restituire un unico argomento.In particular, scalar UDFs are supported where the developers can pass in zero or many arguments and return a single argument result back. Verrà quindi eseguito un controllo per verificare che ciascuno di questi argomenti sia un valore JSON legale.Each of these arguments is checked for being legal JSON values.

La sintassi dell'API SQL di DocumentDB viene estesa per supportare la logica delle applicazioni personalizzata usando le funzioni definite dall'utente.The DocumentDB API SQL syntax is extended to support custom application logic using these User-Defined Functions. Le UDF possono essere registrate con l'API di DocumentDB ed è quindi possibile fare loro riferimento come parte di una query SQL.UDFs can be registered with DocumentDB API and then be referenced as part of a SQL query. In effetti, le UDF sono progettate espressamente per essere richiamate dalle query.In fact, the UDFs are exquisitely designed to be invoked by queries. Come corollario a questa scelta, le UDF non hanno accesso all'oggetto di contesto a cui possono invece accedere altri tipi di Javascript (stored procedure e trigger).As a corollary to this choice, UDFs do not have access to the context object which the other JavaScript types (stored procedures and triggers) have. Poiché le query vengono eseguite in sola lettura, è possibile eseguirle sulle repliche primarie o secondarie.Since queries execute as read-only, they can run either on primary or on secondary replicas. Di conseguenza, a differenza di altri tipi di JavaScript, le UDF vengono progettate per l'esecuzione sulle repliche secondarie.Therefore, UDFs are designed to run on secondary replicas unlike other JavaScript types.

Di seguito è riportato un esempio di come è possibile registrare una UDF nel database di Cosmos DB, in maniera specifica in una raccolta di documenti.Below is an example of how a UDF can be registered at the Cosmos DB database, specifically under a document collection.

   UserDefinedFunction regexMatchUdf = new UserDefinedFunction
   {
       Id = "REGEX_MATCH",
       Body = @"function (input, pattern) { 
                   return input.match(pattern) !== null;
               };",
   };

   UserDefinedFunction createdUdf = client.CreateUserDefinedFunctionAsync(
       UriFactory.CreateDocumentCollectionUri("testdb", "families"), 
       regexMatchUdf).Result;  

Nell'esempio precedente è stata creata una UDF, denominata REGEX_MATCH.The preceding example creates a UDF whose name is REGEX_MATCH. Accetta due valori stringa JSON input and pattern e controlla se il primo corrisponde al modello specificato nel secondo mediante la funzione string.match() di JavaScript.It accepts two JSON string values input and pattern and checks if the first matches the pattern specified in the second using JavaScript's string.match() function.

È ora possibile usare questa UDF in una query in una proiezione.We can now use this UDF in a query in a projection. Le UDF devono essere qualificate con il prefisso con distinzione tra maiuscole e minuscole "udf."UDFs must be qualified with the case-sensitive prefix "udf." quando chiamate dall'interno delle query.when called from within queries.

Nota

Prima del 17/03/2015, Cosmos DB supportava le chiamate UDF senza il prefisso "udf.",Prior to 3/17/2015, Cosmos DB supported UDF calls without the "udf." come SELECT REGEX_MATCH().prefix like SELECT REGEX_MATCH(). Questo modello di chiamata è stato deprecato.This calling pattern has been deprecated.

QueryQuery

SELECT udf.REGEX_MATCH(Families.address.city, ".*eattle")
FROM Families

RisultatiResults

[
  {
    "$1": true
  }, 
  {
    "$1": false
  }
]

È anche possibile usare l'UDF all'interno di un filtro, come mostrato nell'esempio seguente, anch'esso qualificato con ilThe UDF can also be used inside a filter as shown in the example below, also qualified with the "udf." prefisso:prefix:

QueryQuery

SELECT Families.id, Families.address.city
FROM Families
WHERE udf.REGEX_MATCH(Families.address.city, ".*eattle")

RisultatiResults

[{
    "id": "AndersenFamily",
    "city": "Seattle"
}]

In sostanza, le UDF sono espressioni scalari valide che è possibile usare sia nelle proiezioni sia nei filtri.In essence, UDFs are valid scalar expressions and can be used in both projections and filters.

Per ampliare la potenza delle UDF, verrà ora analizzato un altro esempio che prevede la logica condizionale:To expand on the power of UDFs, let's look at another example with conditional logic:

   UserDefinedFunction seaLevelUdf = new UserDefinedFunction()
   {
       Id = "SEALEVEL",
       Body = @"function(city) {
               switch (city) {
                   case 'seattle':
                       return 520;
                   case 'NY':
                       return 410;
                   case 'Chicago':
                       return 673;
                   default:
                       return -1;
                }"
        };

        UserDefinedFunction createdUdf = await client.CreateUserDefinedFunctionAsync(
            UriFactory.CreateDocumentCollectionUri("testdb", "families"), 
            seaLevelUdf);

Di seguito è riportato un esempio per l'esercitazione con le UDF.Below is an example that exercises the UDF.

QueryQuery

SELECT f.address.city, udf.SEALEVEL(f.address.city) AS seaLevel
FROM Families f    

RisultatiResults

 [
  {
    "city": "seattle", 
    "seaLevel": 520
  }, 
  {
    "city": "NY", 
    "seaLevel": 410
  }
]

Come mostrato dagli esempi precedenti, le UDF integrano la potenza del linguaggio JavaScript con quella dell'API SQL di DocumentDB per fornire un'interfaccia programmabile avanzata con la quale eseguire una logica condizionale e procedurale complessa con l'ausilio delle capacità di runtime JavaScript integrate.As the preceding examples showcase, UDFs integrate the power of JavaScript language with the DocumentDB API SQL to provide a rich programmable interface to do complex procedural, conditional logic with the help of inbuilt JavaScript runtime capabilities.

L'API SQL di DocumentDB fornisce gli argomenti alle UDF per ogni documento nel database di origine nella fase corrente (clausola WHERE o clausola SELECT) di elaborazione della UDF.DocumentDB API SQL provides the arguments to the UDFs for each document in the source at the current stage (WHERE clause or SELECT clause) of processing the UDF. Il risultato verrà incorporato in maniera uniforme nella pipeline di esecuzione generale.The result is incorporated in the overall execution pipeline seamlessly. Se le proprietà a cui fanno riferimento i parametri della UDF non sono disponibili nel valore JSON, il parametro verrà considerato come Undefined, quindi la chiamata alla UDF verrà interamente ignorata.If the properties referred to by the UDF parameters are not available in the JSON value, the parameter is considered as undefined and hence the UDF invocation is entirely skipped. Analogamente, se il risultato della UDF è Undefined, non verrà incluso nel risultato.Similarly if the result of the UDF is undefined, it's not included in the result.

Riepilogando, le UDF sono un ottimo strumento per eseguire una logica di business complessa come parte della query.In summary, UDFs are great tools to do complex business logic as part of the query.

Valutazione degli operatoriOperator evaluation

Essendo un database JSON, Cosmos DB esegue un confronto con gli operatori JavaScript e la relativa semantica di valutazione.Cosmos DB, by the virtue of being a JSON database, draws parallels with JavaScript operators and its evaluation semantics. Benché Cosmos DB provi a mantenere la semantica di JavaScript in termini di supporto JSON, la valutazione dell'operazione devia in alcune istanze.While Cosmos DB tries to preserve JavaScript semantics in terms of JSON support, the operation evaluation deviates in some instances.

A differenza del tradizionale linguaggio SQL, nell'API SQL di DocumentDB spesso i tipi di valori non sono noti fino al loro recupero dal database.In DocumentDB API SQL, unlike in traditional SQL, the types of values are often not known until the values are retrieved from database. Per poter eseguire le query in maniera efficiente, gran parte degli operatori ha rigorosi requisiti di tipi.In order to efficiently execute queries, most of the operators have strict type requirements.

L'API SQL di DocumentDB non esegue conversioni implicite, a differenza di JavaScript.DocumentDB API SQL doesn't perform implicit conversions, unlike JavaScript. Ad esempio, una query come SELECT * FROM Person p WHERE p.Age = 21 corrisponde a documenti che contengono una proprietà Age il cui valore è 21.For instance, a query like SELECT * FROM Person p WHERE p.Age = 21 matches documents that contain an Age property whose value is 21. Qualsiasi altro documento la cui proprietà Age corrisponde alla stringa "21", o ad altre possibili variazioni come "021", "21.0", "0021", "00021" e così via, non verrà trovato.Any other document whose Age property matches string "21", or other possibly infinite variations like "021", "21.0", "0021", "00021", etc. will not be matched. Questo comportamento è diverso da quanto avviene in JavaScript, che consente di eseguire implicitamente il cast dei valori di stringa al numero (in base all'operatore, ad esempio: ==).This is in contrast to the JavaScript where the string values are implicitly casted to numbers (based on operator, ex: ==). Questa scelta è fondamentale per la ricerca di indici corrispondenti nell'API SQL di DocumentDB.This choice is crucial for efficient index matching in DocumentDB API SQL.

Query SQL con parametriParameterized SQL queries

Cosmos DB supporta le query con parametri espressi con la consueta notazione @.Cosmos DB supports queries with parameters expressed with the familiar @ notation. SQL con parametri fornisce solide capacità di gestione ed escape dell'input utente, evitando l'esposizione accidentale di dati mediante attacchi SQL injection.Parameterized SQL provides robust handling and escaping of user input, preventing accidental exposure of data through SQL injection.

Ad esempio, è possibile scrivere una query che accetta come parametri il cognome e lo stato di residenza e quindi eseguirla per diversi valori di cognome e stato di residenza in base all'input dell'utente.For example, you can write a query that takes last name and address state as parameters, and then execute it for various values of last name and address state based on user input.

SELECT * 
FROM Families f
WHERE f.lastName = @lastName AND f.address.state = @addressState

Questa richiesta può quindi essere inviata a Cosmos DB come query con parametri JSON, come illustrato di seguito.This request can then be sent to Cosmos DB as a parameterized JSON query like shown below.

{      
    "query": "SELECT * FROM Families f WHERE f.lastName = @lastName AND f.address.state = @addressState",     
    "parameters": [          
        {"name": "@lastName", "value": "Wakefield"},         
        {"name": "@addressState", "value": "NY"},           
    ] 
}

L'argomento può essere impostato su TOP mediante query con parametri, come illustrato di seguito.The argument to TOP can be set using parameterized queries like shown below.

{      
    "query": "SELECT TOP @n * FROM Families",     
    "parameters": [          
        {"name": "@n", "value": 10},         
    ] 
}

I valori dei parametri possono essere qualsiasi valore JSON valido (stringhe, numeri, valori booleani, valori null, persino matrici o valori JSON annidati).Parameter values can be any valid JSON (strings, numbers, Booleans, null, even arrays or nested JSON). Inoltre, dato che Cosmos DB è senza schema, i parametri non vengono convalidati rispetto a qualsiasi tipo.Also since Cosmos DB is schema-less, parameters are not validated against any type.

Funzioni predefiniteBuilt-in functions

Cosmos DB supporta anche una serie di funzioni predefinite per le operazioni comuni, che possono essere usate all'interno di query come le funzioni definite dall'utente (UDF).Cosmos DB also supports a number of built-in functions for common operations, that can be used inside queries like user-defined functions (UDFs).

Gruppo di funzioniFunction group OperazioniOperations
Funzioni matematicheMathematical functions ABS, CEILING, EXP, FLOOR, LOG, LOG10, POWER, ROUND, SIGN, SQRT, SQUARE, TRUNC, ACOS, ASIN, ATAN, ATN2, COS, COT, gradi, PI, radianti, SIN e TANABS, CEILING, EXP, FLOOR, LOG, LOG10, POWER, ROUND, SIGN, SQRT, SQUARE, TRUNC, ACOS, ASIN, ATAN, ATN2, COS, COT, DEGREES, PI, RADIANS, SIN, and TAN
Funzioni di controllo del tipoType checking functions IS_ARRAY, IS_BOOL, IS_NULL, IS_NUMBER, IS_OBJECT, IS_STRING, IS_DEFINED e IS_PRIMITIVEIS_ARRAY, IS_BOOL, IS_NULL, IS_NUMBER, IS_OBJECT, IS_STRING, IS_DEFINED, and IS_PRIMITIVE
Funzioni stringaString functions CONCAT, CONTAINS, ENDSWITH, INDEX_OF, sinistra, lunghezza, inferiore, LTRIM, REPLACE, replica, inversa, destra, RTRIM, STARTSWITH, SUBSTRING e superioreCONCAT, CONTAINS, ENDSWITH, INDEX_OF, LEFT, LENGTH, LOWER, LTRIM, REPLACE, REPLICATE, REVERSE, RIGHT, RTRIM, STARTSWITH, SUBSTRING, and UPPER
Funzioni di matriceArray functions ARRAY_CONCAT, ARRAY_CONTAINS, ARRAY_LENGTH e ARRAY_SLICEARRAY_CONCAT, ARRAY_CONTAINS, ARRAY_LENGTH, and ARRAY_SLICE
Funzioni spazialiSpatial functions ST_DISTANCE, ST_WITHIN, ST_INTERSECTS, ST_ISVALID e ST_ISVALIDDETAILEDST_DISTANCE, ST_WITHIN, ST_INTERSECTS, ST_ISVALID, and ST_ISVALIDDETAILED

Se attualmente si usa una funzione definita dall'utente (UDF) per cui è ora disponibile una funzione predefinita, è consigliabile usare la corrispondente funzione predefinita perché la sua esecuzione sarà più rapida ed efficiente.If you’re currently using a user-defined function (UDF) for which a built-in function is now available, you should use the corresponding built-in function as it is going to be quicker to run and more efficiently.

Funzioni matematicheMathematical functions

Le funzioni matematiche eseguono un calcolo basato su valori di input passati come argomenti e restituiscono un valore numerico.The mathematical functions each perform a calculation, based on input values that are provided as arguments, and return a numeric value. Di seguito è riportata una tabella delle funzioni matematiche predefinite supportate.Here’s a table of supported built-in mathematical functions.

UsoUsage DescrizioneDescription
[ABS (num_expr)[ABS (num_expr) Restituisce il valore assoluto (positivo) dell'espressione numerica specificata.Returns the absolute (positive) value of the specified numeric expression.
CEILING (num_expr)CEILING (num_expr) Restituisce il più piccolo valore integer maggiore di o uguale all'espressione numerica specificata.Returns the smallest integer value greater than, or equal to, the specified numeric expression.
FLOOR (num_expr)FLOOR (num_expr) Restituisce il valore integer più alto, minore di o uguale all'espressione numerica specificata.Returns the largest integer less than or equal to the specified numeric expression.
EXP (num_expr)EXP (num_expr) Restituisce l'esponente dell'espressione numerica specificata.Returns the exponent of the specified numeric expression.
LOG (num_expr [,base])LOG (num_expr [,base]) Restituisce il logaritmo naturale dell'espressione numerica specificata oppure il logaritmo usando la base specificataReturns the natural logarithm of the specified numeric expression, or the logarithm using the specified base
LOG10 (num_expr)LOG10 (num_expr) Restituisce il valore logaritmico in base 10 dell'espressione numerica specificata.Returns the base-10 logarithmic value of the specified numeric expression.
ROUND (num_expr)ROUND (num_expr) Restituisce un valore numerico, arrotondato al valore integer più vicino.Returns a numeric value, rounded to the closest integer value.
TRUNC (num_expr)TRUNC (num_expr) Restituisce un valore numerico, troncato al valore integer più vicino.Returns a numeric value, truncated to the closest integer value.
SQRT (num_expr)SQRT (num_expr) Restituisce la radica quadrata dell'espressione numerica specificata.Returns the square root of the specified numeric expression.
SQUARE (num_expr)SQUARE (num_expr) Restituisce il quadrato dell'espressione numerica specificata.Returns the square of the specified numeric expression.
POWER (num_expr, num_expr)POWER (num_expr, num_expr) Restituisce la potenza dell'espressione numerica specificata al valore specificato.Returns the power of the specified numeric expression to the value specified.
SIGN (num_expr)SIGN (num_expr) Restituisce il valore del segno (-1, 0, 1) dell'espressione numerica specificata.Returns the sign value (-1, 0, 1) of the specified numeric expression.
ACOS (num_expr)ACOS (num_expr) Restituisce l'angolo, espresso in radianti, il cui coseno corrisponde all'espressione numerica specificata. Denominato anche arcocoseno.Returns the angle, in radians, whose cosine is the specified numeric expression; also called arccosine.
ASIN (num_expr)ASIN (num_expr) Restituisce l'angolo, espresso in radianti, il cui seno è l'espressione numerica specificata.Returns the angle, in radians, whose sine is the specified numeric expression. Detta anche arcoseno.This is also called arcsine.
ATAN (num_expr)ATAN (num_expr) Restituisce l'angolo, espresso in radianti, la cui tangente è l'espressione numerica specificata.Returns the angle, in radians, whose tangent is the specified numeric expression. Detta anche arcotangente.This is also called arctangent.
ATN2 (num_expr)ATN2 (num_expr) Restituisce l'angolo, espresso in radianti, tra l'asse x positivo e il raggio dall'origine al punto (y, x), dove x e y sono i valori delle due espressioni float specificate.Returns the angle, in radians, between the positive x-axis and the ray from the origin to the point (y, x), where x and y are the values of the two specified float expressions.
COS (num_expr)COS (num_expr) Restituisce il coseno trigonometrico dell'angolo specificato, espresso in radianti, nell'espressione specificata.Returns the trigonometric cosine of the specified angle, in radians, in the specified expression.
COT (num_expr)COT (num_expr) Restituisce la cotangente trigonometrica dell'angolo specificato, espresso in radianti, nell'espressione numerica specificata.Returns the trigonometric cotangent of the specified angle, in radians, in the specified numeric expression.
DEGREES (num_expr)DEGREES (num_expr) Restituisce l'angolo corrispondente in gradi di un angolo specificato in radianti.Returns the corresponding angle in degrees for an angle specified in radians.
PI ()PI () Restituisce il valore costante di pi greco.Returns the constant value of PI.
RADIANS (num_expr)RADIANS (num_expr) Restituisce radianti quando viene immessa un'espressione numerica, espresso in gradi.Returns radians when a numeric expression, in degrees, is entered.
SIN (num_expr)SIN (num_expr) Restituisce il seno trigonometrico dell'angolo specificato, espresso in radianti, nell'espressione specificata.Returns the trigonometric sine of the specified angle, in radians, in the specified expression.
TAN (num_expr)TAN (num_expr) Restituisce la tangente dell'espressione di input nell'espressione specificata.Returns the tangent of the input expression, in the specified expression.

Ad esempio, è ora possibile eseguire query come le seguenti:For example, you can now run queries like the following:

QueryQuery

SELECT VALUE ABS(-4)

RisultatiResults

[4]

La differenza principale tra le funzioni di Cosmos DB rispetto ad ANSI SQL è che sono progettate per interagire correttamente con dati senza schema e con schema misto.The main difference between Cosmos DB’s functions compared to ANSI SQL is that they are designed to work well with schema-less and mixed schema data. Se ad esempio si ha un documento in cui manca la proprietà Size oppure caratterizzato da un valore non numerico, come "unknown", il documento viene ignorato invece di restituire un errore.For example, if you have a document where the Size property is missing, or has a non-numeric value like “unknown”, then the document is skipped over, instead of returning an error.

Funzioni di controllo del tipoType checking functions

Le funzioni di controllo del tipo consentono di controllare il tipo di un'espressione nell'ambito delle query SQL.The type checking functions allow you to check the type of an expression within SQL queries. Le funzioni di controllo del tipo possono essere usate per determinare il tipo di proprietà all'interno dei documenti al volo, quando è variabile o sconosciuto.Type checking functions can be used to determine the type of properties within documents on the fly when it is variable or unknown. Di seguito è riportata una tabella di funzioni predefinite di controllo del tipo supportate.Here’s a table of supported built-in type checking functions.

UtilizzoUsage DescrizioneDescription
IS_ARRAY (expr)IS_ARRAY (expr) Restituisce un valore booleano che indica se il tipo del valore è una matrice.Returns a Boolean indicating if the type of the value is an array.
IS_BOOL (expr)IS_BOOL (expr) Restituisce un valore booleano che indica se il tipo del valore è booleano.Returns a Boolean indicating if the type of the value is a Boolean.
IS_NULL (expr)IS_NULL (expr) Restituisce un valore booleano che indica se il tipo del valore è Null.Returns a Boolean indicating if the type of the value is null.
IS_NUMBER (expr)IS_NUMBER (expr) Restituisce un valore booleano che indica se il tipo del valore è un numero.Returns a Boolean indicating if the type of the value is a number.
IS_OBJECT (expr)IS_OBJECT (expr) Restituisce un valore booleano che indica se il tipo del valore è un oggetto JSON.Returns a Boolean indicating if the type of the value is a JSON object.
IS_STRING (expr)IS_STRING (expr) Restituisce un valore booleano che indica se il tipo del valore è una stringa.Returns a Boolean indicating if the type of the value is a string.
IS_DEFINED (expr)IS_DEFINED (expr) Restituisce un valore booleano che indica se alla proprietà è stata assegnato un valore.Returns a Boolean indicating if the property has been assigned a value.
IS_PRIMITIVE (expr)IS_PRIMITIVE (expr) Restituisce un valore booleano che indica se il tipo del valore è stringa, numero, valore booleano o Null.Returns a Boolean indicating if the type of the value is a string, number, Boolean or null.

Usando queste funzioni, è ora possibile eseguire query come le seguenti:Using these functions, you can now run queries like the following:

QueryQuery

SELECT VALUE IS_NUMBER(-4)

RisultatiResults

[true]

Funzioni stringaString functions

Le funzioni scalari seguenti eseguono un'operazione su un valore di stringa di input e restituiscono una stringa, il valore numerico o booleano.The following scalar functions perform an operation on a string input value and return a string, numeric or Boolean value. Ecco una tabella di funzioni per stringhe:Here's a table of built-in string functions:

UsoUsage DescriptionDescription
LENGTH (str_expr)LENGTH (str_expr) Restituisce il numero di caratteri dell'espressione stringa specificataReturns the number of characters of the specified string expression
CONCAT (str_expr, str_expr [, str_expr])CONCAT (str_expr, str_expr [, str_expr]) Restituisce una stringa che rappresenta il risultato della concatenazione di due o più valori di stringa.Returns a string that is the result of concatenating two or more string values.
SUBSTRING (str_expr, num_expr, num_expr)SUBSTRING (str_expr, num_expr, num_expr) Restituisce parte di un'espressione stringa.Returns part of a string expression.
STARTSWITH (str_expr, str_expr)STARTSWITH (str_expr, str_expr) Restituisce un valore booleano che indica se la prima espressione stringa termina con il secondo.Returns a Boolean indicating whether the first string expression ends with the second
ENDSWITH (str_expr, str_expr)ENDSWITH (str_expr, str_expr) Restituisce un valore booleano che indica se la prima espressione stringa termina con il secondo.Returns a Boolean indicating whether the first string expression ends with the second
CONTAINS (str_expr, str_expr)CONTAINS (str_expr, str_expr) Restituisce un valore booleano che indica se la prima espressione stringa contiene il secondo.Returns a Boolean indicating whether the first string expression contains the second.
INDEX_OF (str_expr, str_expr)INDEX_OF (str_expr, str_expr) Restituisce la posizione iniziale della prima occorrenza della seconda stringa di espressione all'interno della prima espressione stringa specificata oppure -1 se la stringa non viene trovata.Returns the starting position of the first occurrence of the second string expression within the first specified string expression, or -1 if the string is not found.
LEFT (str_expr, num_expr)LEFT (str_expr, num_expr) Restituisce la parte sinistra di una stringa con il numero specificato di caratteri.Returns the left part of a string with the specified number of characters.
RIGHT (str_expr, num_expr)RIGHT (str_expr, num_expr) Restituisce la parte destra di una stringa con il numero specificato di caratteri.Returns the right part of a string with the specified number of characters.
LTRIM (str_expr)LTRIM (str_expr) Restituisce un'espressione stringa dopo aver rimosso gli spazi vuoti iniziali.Returns a string expression after it removes leading blanks.
RTRIM (str_expr)RTRIM (str_expr) Restituisce un'espressione stringa dopo la rimozione di tutti gli spazi vuoti finali.Returns a string expression after truncating all trailing blanks.
LOWER (str_expr)LOWER (str_expr) Restituisce un'espressione stringa dopo la conversione di dati in caratteri maiuscoli in caratteri minuscoli.Returns a string expression after converting uppercase character data to lowercase.
UPPER (str_expr)UPPER (str_expr) Restituisce un'espressione stringa dopo aver convertito i caratteri minuscoli in caratteri maiuscoli.Returns a string expression after converting lowercase character data to uppercase.
REPLACE (str_expr, str_expr, str_expr)REPLACE (str_expr, str_expr, str_expr) Sostituisce tutte le occorrenze di un valore stringa specificato con un altro valore stringa.Replaces all occurrences of a specified string value with another string value.
REPLICATE (str_expr, num_expr)REPLICATE (str_expr, num_expr) Ripete un valore stringa in un numero di volte specificato.Repeats a string value a specified number of times.
REVERSE (str_expr)REVERSE (str_expr) Restituisce l'inverso di un valore stringa.Returns the reverse order of a string value.

Usando queste funzioni, è ora possibile eseguire query come le seguenti.Using these functions, you can now run queries like the following. Ad esempio, è possibile restituire il nome della famiglia in lettere maiuscole come segue:For example, you can return the family name in uppercase as follows:

QueryQuery

SELECT VALUE UPPER(Families.id)
FROM Families

RisultatiResults

[
    "WAKEFIELDFAMILY", 
    "ANDERSENFAMILY"
]

In alternativa, è possibile concatenare stringhe come in questo esempio:Or concatenate strings like in this example:

QueryQuery

SELECT Families.id, CONCAT(Families.address.city, ",", Families.address.state) AS location
FROM Families

RisultatiResults

[{
  "id": "WakefieldFamily",
  "location": "NY,NY"
},
{
  "id": "AndersenFamily",
  "location": "seattle,WA"
}]

Le funzioni stringa possono essere usate anche nella clausola WHERE per filtrare i risultati, come nell'esempio seguente:String functions can also be used in the WHERE clause to filter results, like in the following example:

QueryQuery

SELECT Families.id, Families.address.city
FROM Families
WHERE STARTSWITH(Families.id, "Wakefield")

RisultatiResults

[{
  "id": "WakefieldFamily",
  "city": "NY"
}]

Funzioni di matriceArray functions

Le funzioni scalari seguenti eseguono un'operazione su un valore di input di matrice e restituiscono un valore numerico, booleano o matrice.The following scalar functions perform an operation on an array input value and return numeric, Boolean or array value. La tabella seguente include funzioni di matrice predefinite:Here's a table of built-in array functions:

UsoUsage DescriptionDescription
ARRAY_LENGTH (arr_expr)ARRAY_LENGTH (arr_expr) Restituisce il numero di elementi dell'espressione di matrice specificato.Returns the number of elements of the specified array expression.
ARRAY_CONCAT (arr_expr, arr_expr [, arr_expr])ARRAY_CONCAT (arr_expr, arr_expr [, arr_expr]) Restituisce una matrice che rappresenta il risultato della concatenazione di due o più valori della matrice.Returns an array that is the result of concatenating two or more array values.
ARRAY_CONTAINS (arr_expr, expr [, bool_expr])ARRAY_CONTAINS (arr_expr, expr [, bool_expr]) Restituisce un valore booleano che indica se la matrice contiene il valore specificato.Returns a Boolean indicating whether the array contains the specified value. Può specificare se la corrispondenza è completa o parziale.Can specify if the match is full or partial.
ARRAY_SLICE (arr_expr, num_expr [, num_expr])ARRAY_SLICE (arr_expr, num_expr [, num_expr]) Restituisce parte di un'espressione di matrice.Returns part of an array expression.

Le funzioni di matrice possono essere usate per manipolare le matrici in JSON.Array functions can be used to manipulate arrays within JSON. Ad esempio, la query seguente restituisce tutti i documenti in cui uno dei genitori è "Robin Wakefield".For example, here's a query that returns all documents where one of the parents is "Robin Wakefield".

QueryQuery

SELECT Families.id 
FROM Families 
WHERE ARRAY_CONTAINS(Families.parents, { givenName: "Robin", familyName: "Wakefield" })

RisultatiResults

[{
  "id": "WakefieldFamily"
}]

È possibile specificare un frammento parziale per la corrispondenza di elementi all'interno della matrice.You can specify a partial fragment for matching elements within the array. La query seguente trova tutti gli elementi padre con givenName di Robin.The following query finds all parents with the givenName of Robin.

QueryQuery

SELECT Families.id 
FROM Families 
WHERE ARRAY_CONTAINS(Families.parents, { givenName: "Robin" }, true)

RisultatiResults

[{
  "id": "WakefieldFamily"
}]

L'esempio seguente usa ARRAY_LENGTH per ottenere il numero di figli per ogni famiglia.Here's another example that uses ARRAY_LENGTH to get the number of children per family.

QueryQuery

SELECT Families.id, ARRAY_LENGTH(Families.children) AS numberOfChildren
FROM Families 

RisultatiResults

[{
  "id": "WakefieldFamily",
  "numberOfChildren": 2
},
{
  "id": "AndersenFamily",
  "numberOfChildren": 1
}]

Funzioni spazialiSpatial functions

Cosmos DB supporta le seguenti funzioni predefinite di Open Geospatial Consortium (OGC) per l'esecuzione di query geospaziali.Cosmos DB supports the following Open Geospatial Consortium (OGC) built-in functions for geospatial querying.

UtilizzoUsage DescrizioneDescription
ST_DISTANCE (point_expr, point_expr)ST_DISTANCE (point_expr, point_expr) Restituisce la distanza tra le due espressioni GeoJSON punto, poligono o LineString.Returns the distance between the two GeoJSON Point, Polygon, or LineString expressions.
ST_WITHIN (point_expr, polygon_expr)ST_WITHIN (point_expr, polygon_expr) Restituisce un'espressione booleana che indica se il primo oggetto GeoJSON (punto, poligono o LineString) è all'interno del secondo oggetto GeoJSON (punto, poligono o LineString).Returns a Boolean expression indicating whether the first GeoJSON object (Point, Polygon, or LineString) is within the second GeoJSON object (Point, Polygon, or LineString).
ST_INTERSECTS (spatial_expr, spatial_expr)ST_INTERSECTS (spatial_expr, spatial_expr) Restituisce un'espressione booleana che indica se i due oggetti GeoJSON specificati (punto, poligono o LineString) si intersecano.Returns a Boolean expression indicating whether the two specified GeoJSON objects (Point, Polygon, or LineString) intersect.
ST_ISVALIDST_ISVALID Restituisce un valore booleano che indica se l'espressione GeoJSON punto, poligono o LineString specificata è valida.Returns a Boolean value indicating whether the specified GeoJSON Point, Polygon, or LineString expression is valid.
ST_ISVALIDDETAILEDST_ISVALIDDETAILED Restituisce un valore JSON che contiene un valore booleano valore se l'espressione GeoJSON punto, poligono o LineString specificata è valida e, se non valida, anche il motivo come valore stringa.Returns a JSON value containing a Boolean value if the specified GeoJSON Point, Polygon, or LineString expression is valid, and if invalid, additionally the reason as a string value.

Le funzioni spaziali possono essere utilizzate per eseguire query di prossimità rispetto ai dati spaziali.Spatial functions can be used to perform proximity queries against spatial data. Ad esempio, di seguito è riportata una query che restituisce tutti i documenti della famiglia entro 30 km della posizione specificata utilizzando la funzione predefinita ST_DISTANCE.For example, here's a query that returns all family documents that are within 30 km of the specified location using the ST_DISTANCE built-in function.

QueryQuery

SELECT f.id 
FROM Families f 
WHERE ST_DISTANCE(f.location, {'type': 'Point', 'coordinates':[31.9, -4.8]}) < 30000

RisultatiResults

[{
  "id": "WakefieldFamily"
}]

Per informazioni dettagliate sul supporto geospaziale in Cosmos DB, vedere Uso dei dati geospaziali in Azure Cosmos DB.For more details on geospatial support in Cosmos DB, please see Working with geospatial data in Azure Cosmos DB. Viene eseguito il wrapping di funzioni spaziali e della sintassi SQL per Cosmos DB.That wraps up spatial functions, and the SQL syntax for Cosmos DB. Verrà ora esaminato il funzionamento delle query LINQ e verrà illustrato il modo in cui interagiscono con la sintassi esaminata fino ad ora.Now let's take a look at how LINQ querying works and how it interacts with the syntax we've seen so far.

Da LINQ all'API SQL di DocumentDBLINQ to DocumentDB API SQL

LINQ è un modello di programmazione .NET che esprime il calcolo come query su flussi di oggetti.LINQ is a .NET programming model that expresses computation as queries on streams of objects. Cosmos DB fornisce una libreria lato client che si interfaccia con LINQ agevolando una conversione tra oggetti JSON e .NET e un mapping da un sottoinsieme di query LINQ alle query di Cosmos DB.Cosmos DB provides a client-side library to interface with LINQ by facilitating a conversion between JSON and .NET objects and a mapping from a subset of LINQ queries to Cosmos DB queries.

L'immagine seguente illustra l'architettura di supporto delle query LINQ usando Cosmos DB.The picture below shows the architecture of supporting LINQ queries using Cosmos DB. Con il client di Cosmos DB, gli sviluppatori possono creare un oggetto IQueryable che comunica una query al provider di query di Cosmos DB, il quale a sua volta traduce la query LINQ in una query di Cosmos DB.Using the Cosmos DB client, developers can create an IQueryable object that directly queries the Cosmos DB query provider, which then translates the LINQ query into a Cosmos DB query. Questa viene quindi passata al server di Cosmos DB per recuperare un set di risultati in formato JSON.The query is then passed to the Cosmos DB server to retrieve a set of results in JSON format. I risultati restituiti vengono deserializzati in un flusso di oggetti .NET sul lato client.The returned results are deserialized into a stream of .NET objects on the client side.

Architettura di supporto delle query LINQ usando API DocumentDB - Sintassi SQL, linguaggio di query JSON, concetti relativi ai database e query SQL

Mapping .NET e JSON.NET and JSON mapping

Il mapping tra oggetti .NET e documenti JSON avviene naturalmente: ogni campo del membro dati viene mappato a un oggetto JSON, in cui il nome del campo viene mappato alla parte "chiave" dell'oggetto e la parte "valore" viene mappata in modo ricorsivo alla parte del valore dell'oggetto.The mapping between .NET objects and JSON documents is natural - each data member field is mapped to a JSON object, where the field name is mapped to the "key" part of the object and the "value" part is recursively mapped to the value part of the object. Si consideri l'esempio seguente: l'oggetto Family creato viene mappato al documento JSON, come illustrato di seguito.Consider the following example: The Family object created is mapped to the JSON document as shown below. Viceversa, il documento JSON viene mappato nuovamente a un oggetto .NET.And vice versa, the JSON document is mapped back to a .NET object.

Classe C#C# Class

public class Family
{
    [JsonProperty(PropertyName="id")]
    public string Id;
    public Parent[] parents;
    public Child[] children;
    public bool isRegistered;
};

public struct Parent
{
    public string familyName;
    public string givenName;
};

public class Child
{
    public string familyName;
    public string givenName;
    public string gender;
    public int grade;
    public List<Pet> pets;
};

public class Pet
{
    public string givenName;
};

public class Address
{
    public string state;
    public string county;
    public string city;
};

// Create a Family object.
Parent mother = new Parent { familyName= "Wakefield", givenName="Robin" };
Parent father = new Parent { familyName = "Miller", givenName = "Ben" };
Child child = new Child { familyName="Merriam", givenName="Jesse", gender="female", grade=1 };
Pet pet = new Pet { givenName = "Fluffy" };
Address address = new Address { state = "NY", county = "Manhattan", city = "NY" };
Family family = new Family { Id = "WakefieldFamily", parents = new Parent [] { mother, father}, children = new Child[] { child }, isRegistered = false };

JSONJSON

{
    "id": "WakefieldFamily",
    "parents": [
        { "familyName": "Wakefield", "givenName": "Robin" },
        { "familyName": "Miller", "givenName": "Ben" }
    ],
    "children": [
        {
            "familyName": "Merriam", 
            "givenName": "Jesse", 
            "gender": "female", 
            "grade": 1,
            "pets": [
                { "givenName": "Goofy" },
                { "givenName": "Shadow" }
            ]
        },
        { 
          "familyName": "Miller", 
          "givenName": "Lisa", 
          "gender": "female", 
          "grade": 8 
        }
    ],
    "address": { "state": "NY", "county": "Manhattan", "city": "NY" },
    "isRegistered": false
};

Traduzione LINQ in SQLLINQ to SQL translation

Il provider di query di Cosmos DB esegue con il massimo impegno un mapping da una query LINQ a una query SQL di Cosmos DB.The Cosmos DB query provider performs a best effort mapping from a LINQ query into a Cosmos DB SQL query. Nella descrizione seguente si presuppone che il lettore abbia una certa familiarità con LINQ.In the following description, we assume the reader has a basic familiarity of LINQ.

In primo luogo, per il sistema di tipi sono supportati tutti i tipi primitivi JSON: tipi numerici, booleani, stringa e null.First, for the type system, we support all JSON primitive types – numeric types, boolean, string, and null. Sono supportati solo questi tipi JSON.Only these JSON types are supported. Sono supportate le seguenti espressioni scalari.The following scalar expressions are supported.

  • Valori costanti: includono i valori costanti dei tipo di dati primitivi al momento della valutazione della query.Constant values – these include constant values of the primitive data types at the time the query is evaluated.
  • Espressioni indice della matrice/di proprietà: queste espressioni si riferiscono alla proprietà di un oggetto o di un elemento matrice.Property/array index expressions – these expressions refer to the property of an object or an array element.

    family.Id; family.children[0].familyName; family.children[0].grade; family.children[n].grade; //n è una variabile di tipo intfamily.Id; family.children[0].familyName; family.children[0].grade; family.children[n].grade; //n is an int variable

  • Espressioni aritmetiche: includono espressioni aritmetiche comuni su valori numerici e booleani.Arithmetic expressions - These include common arithmetic expressions on numerical and boolean values. Per un elenco completo, fare riferimento alle specifiche di SQL.For the complete list, refer to the SQL specification.

    2 * family.children[0].grade; x + y;2 * family.children[0].grade; x + y;

  • Espressione di confronto stringhe: includono il confronto di un valore di stringa con un valore di stringa costante.String comparison expression - these include comparing a string value to some constant string value.

    mother.familyName == "Smith"; child.givenName == s; //s è una variabile di stringamother.familyName == "Smith"; child.givenName == s; //s is a string variable

  • Espressione di creazione oggetto/matrice: restituisce un oggetto di tipo valore composito o tipo anonimo o ancora un matrice di tali oggetti.Object/array creation expression - these expressions return an object of compound value type or anonymous type or an array of such objects. Questi valori non possono essere annidati.These values can be nested.

    new Parent { familyName = "Smith", givenName = "Joe" }; new { first = 1, second = 2 }; //un tipo anonimo con due campinew Parent { familyName = "Smith", givenName = "Joe" }; new { first = 1, second = 2 }; //an anonymous type with two fields
    new int[] { 3, child.grade, 5 };new int[] { 3, child.grade, 5 };

Elenco di operatori LINQ supportatiList of supported LINQ operators

Di seguito è riportato un elenco di operatori LINQ supportati nel provider LINQ incluso in DocumentDB .NET SDK.Here is a list of supported LINQ operators in the LINQ provider included with the DocumentDB .NET SDK.

  • Select: le proiezioni convertono in SQL SELECT inclusa la costruzione dell'oggetto.Select: Projections translate to the SQL SELECT including object construction
  • Where: i filtri convertono in SQL WHERE e supportano la conversione tra && , || e !Where: Filters translate to the SQL WHERE, and support translation between && , || and ! in operatori SQL.to the SQL operators
  • SelectMany: consente la rimozione di matrici nella clausola SQL JOIN.SelectMany: Allows unwinding of arrays to the SQL JOIN clause. Può essere usato per concatenare/annidare le espressioni per filtrare in base agli elementi della matrice.Can be used to chain/nest expressions to filter on array elements
  • OrderBy e OrderByDescending: converte in ORDER BY crescente o decrescente.OrderBy and OrderByDescending: Translates to ORDER BY ascending/descending
  • Operatori di aggregazione Count, Sum, Min, Max e Average e relativi equivalenti asincroni CountAsync, SumAsync, MinAsync, MaxAsync e AverageAsync.Count, Sum, Min, Max, and Average operators for aggregation, and their async equivalents CountAsync, SumAsync, MinAsync, MaxAsync, and AverageAsync.
  • CompareTo: converte in confronti di intervallo.CompareTo: Translates to range comparisons. In genere usato per le stringhe in quanto non sono confrontabili in .NETCommonly used for strings since they’re not comparable in .NET
  • Take: converte in SQL TOP per limitare i risultati da una query.Take: Translates to the SQL TOP for limiting results from a query
  • Math Functions: supporta la conversione da Abs, Acos, Asin, Atan, Ceiling, Cos, Exp, Floor, Log, Log10, Pow, Round, Sign, Sin, Sqrt, Tan e Truncate di .NET nelle funzioni predefinite di SQL equivalenti.Math Functions: Supports translation from .NET’s Abs, Acos, Asin, Atan, Ceiling, Cos, Exp, Floor, Log, Log10, Pow, Round, Sign, Sin, Sqrt, Tan, Truncate to the equivalent SQL built-in functions.
  • String Functions: supporta la conversione da Concat, Contains, EndsWith, IndexOf, Count, ToLower, TrimStart, Replace, Reverse, TrimEnd, StartsWith, SubString e ToUpper di .NET nelle funzioni predefinite di SQL equivalenti.String Functions: Supports translation from .NET’s Concat, Contains, EndsWith, IndexOf, Count, ToLower, TrimStart, Replace, Reverse, TrimEnd, StartsWith, SubString, ToUpper to the equivalent SQL built-in functions.
  • Array Functions: supporta la conversione da Concat, Contains e Count di .NET nelle funzioni predefinite di SQL equivalenti.Array Functions: Supports translation from .NET’s Concat, Contains, and Count to the equivalent SQL built-in functions.
  • Geospatial Extension Functions: supporta la conversione dai metodi sthub Distance, Within, IsValid e IsValidDetailed nelle funzioni predefinite di SQL equivalenti.Geospatial Extension Functions: Supports translation from stub methods Distance, Within, IsValid, and IsValidDetailed to the equivalent SQL built-in functions.
  • User Defined Function Extension Function: supporta la conversione dal metodo stub UserDefinedFunctionProvider.Invoke alla funzione corrispondente definita dall'utente.User-Defined Function Extension Function: Supports translation from the stub method UserDefinedFunctionProvider.Invoke to the corresponding user-defined function.
  • Miscellaneous: supporta la conversione degli operatori condizionali e di unione.Miscellaneous: Supports translation of the coalesce and conditional operators. Consente la conversione di Contains in String CONTAINS, ARRAY_CONTAINS o SQL IN in base al contesto.Can translate Contains to String CONTAINS, ARRAY_CONTAINS, or the SQL IN depending on context.

Operatori di query SQLSQL query operators

Di seguito sono riportati alcuni esempi che illustrano in che modo gli operatori di query LINQ standard vengono tradotti in query di Cosmos DB.Here are some examples that illustrate how some of the standard LINQ query operators are translated down to Cosmos DB queries.

Operatore SelectSelect Operator

La sintassi è input.Select(x => f(x)), dove f è un'espressione scalare.The syntax is input.Select(x => f(x)), where f is a scalar expression.

Espressione lambda LINQLINQ lambda expression

input.Select(family => family.parents[0].familyName);

SQLSQL

SELECT VALUE f.parents[0].familyName
FROM Families f

Espressione lambda LINQLINQ lambda expression

input.Select(family => family.children[0].grade + c); // c is an int variable

SQLSQL

SELECT VALUE f.children[0].grade + c
FROM Families f 

Espressione lambda LINQLINQ lambda expression

input.Select(family => new
{
    name = family.children[0].familyName,
    grade = family.children[0].grade + 3
});

SQLSQL

SELECT VALUE {"name":f.children[0].familyName, 
              "grade": f.children[0].grade + 3 }
FROM Families f

Operatore SelectManySelectMany operator

La sintassi è input.SelectMany(x => f(x)), dove f è un'espressione scalare che restituisce un tipo di raccolta.The syntax is input.SelectMany(x => f(x)), where f is a scalar expression that returns a collection type.

Espressione lambda LINQLINQ lambda expression

input.SelectMany(family => family.children);

SQLSQL

SELECT VALUE child
FROM child IN Families.children

Operatore WhereWhere operator

La sintassi è input.Where(x => f(x)), dove f è un'espressione scalare che restituisce un valore booleano.The syntax is input.Where(x => f(x)), where f is a scalar expression, which returns a Boolean value.

Espressione lambda LINQLINQ lambda expression

input.Where(family=> family.parents[0].familyName == "Smith");

SQLSQL

SELECT *
FROM Families f
WHERE f.parents[0].familyName = "Smith" 

Espressione lambda LINQLINQ lambda expression

input.Where(
    family => family.parents[0].familyName == "Smith" && 
    family.children[0].grade < 3);

SQLSQL

SELECT *
FROM Families f
WHERE f.parents[0].familyName = "Smith"
AND f.children[0].grade < 3

Query SQL composteComposite SQL queries

Gli operatori sopra riportati possono essere composti in modo da formare query più potenti.The above operators can be composed to form more powerful queries. Poiché Cosmos DB supporta raccolte nidificate, la composizione può essere concatenata o annidata.Since Cosmos DB supports nested collections, the composition can either be concatenated or nested.

ConcatenazioneConcatenation

La sintassi è input(.|.SelectMany())(.Select()|.Where())*.The syntax is input(.|.SelectMany())(.Select()|.Where())*. Una query concatenata può iniziare con una query SelectMany facoltativa, seguita da più operatori Select o Where.A concatenated query can start with an optional SelectMany query followed by multiple Select or Where operators.

Espressione lambda LINQLINQ lambda expression

input.Select(family=>family.parents[0])
    .Where(familyName == "Smith");

SQLSQL

SELECT *
FROM Families f
WHERE f.parents[0].familyName = "Smith"

Espressione lambda LINQLINQ lambda expression

input.Where(family => family.children[0].grade > 3)
    .Select(family => family.parents[0].familyName);

SQLSQL

SELECT VALUE f.parents[0].familyName
FROM Families f
WHERE f.children[0].grade > 3

Espressione lambda LINQLINQ lambda expression

input.Select(family => new { grade=family.children[0].grade}).
    Where(anon=> anon.grade < 3);

SQLSQL

SELECT *
FROM Families f
WHERE ({grade: f.children[0].grade}.grade > 3)

Espressione lambda LINQLINQ lambda expression

input.SelectMany(family => family.parents)
    .Where(parent => parents.familyName == "Smith");

SQLSQL

SELECT *
FROM p IN Families.parents
WHERE p.familyName = "Smith"

AnnidamentoNesting

La sintassi è input.SelectMany(x=>x.Q()) dove Q è un operatore Select, SelectMany o Where.The syntax is input.SelectMany(x=>x.Q()) where Q is a Select, SelectMany, or Where operator.

In una query annidata, la query più interna viene applicata a ogni elemento della raccolta esterna.In a nested query, the inner query is applied to each element of the outer collection. Una funzionalità importante è che la query interna può riferirsi ai campi degli elementi nella raccolta esterna come a self-join.One important feature is that the inner query can refer to the fields of the elements in the outer collection like self-joins.

Espressione lambda LINQLINQ lambda expression

input.SelectMany(family=> 
    family.parents.Select(p => p.familyName));

SQLSQL

SELECT VALUE p.familyName
FROM Families f
JOIN p IN f.parents

Espressione lambda LINQLINQ lambda expression

input.SelectMany(family => 
    family.children.Where(child => child.familyName == "Jeff"));

SQLSQL

SELECT *
FROM Families f
JOIN c IN f.children
WHERE c.familyName = "Jeff"

Espressione lambda LINQLINQ lambda expression

input.SelectMany(family => family.children.Where(
    child => child.familyName == family.parents[0].familyName));

SQLSQL

SELECT *
FROM Families f
JOIN c IN f.children
WHERE c.familyName = f.parents[0].familyName

Esecuzione di query SQLExecuting SQL queries

Cosmos DB espone risorse tramite un'API REST che può essere chiamata da qualsiasi linguaggio in grado di effettuare richieste HTTP/HTTPS.Cosmos DB exposes resources through a REST API that can be called by any language capable of making HTTP/HTTPS requests. In Cosmos DB sono anche disponibili librerie di programmazione per diversi linguaggi comuni, come NET, Node.js, JavaScript e Python.Additionally, Cosmos DB offers programming libraries for several popular languages like .NET, Node.js, JavaScript, and Python. L'API REST e le varie librerie supportano tutte l'esecuzione di query tramite SQL.The REST API and the various libraries all support querying through SQL. .NET SDK supporta l'esecuzione di query LINQ oltre a SQL.The .NET SDK supports LINQ querying in addition to SQL.

Negli esempi seguenti viene illustrato come creare una query e inviarla a fronte di un account di database di Cosmos DB.The following examples show how to create a query and submit it against a Cosmos DB database account.

API RESTREST API

Cosmos DB offre un modello di programmazione aperto RESTful su HTTP.Cosmos DB offers an open RESTful programming model over HTTP. È possibile effettuare il provisioning degli account di database usando una sottoscrizione di Azure.Database accounts can be provisioned using an Azure subscription. Il modello di risorse di Cosmos DB è costituito da un set di risorse disponibili in un account di database e indirizzabili singolarmente tramite un URI logico e stabile.The Cosmos DB resource model consists of a set of resources under a database account, each of which is addressable using a logical and stable URI. Un insieme di risorse viene definito feed nel presente documento.A set of resources is referred to as a feed in this document. Un account di database è costituito da un set di database, ognuno dei quali include più raccolte, che possono contenere documenti, UDF e altri tipi di risorse.A database account consists of a set of databases, each containing multiple collections, each of which in-turn contain documents, UDFs, and other resource types.

Il modello di interazione di base con queste risorse usa i verbi HTTP GET, PUT, POST e DELETE con la relativa interpretazione standard.The basic interaction model with these resources is through the HTTP verbs GET, PUT, POST, and DELETE with their standard interpretation. Il verbo POST viene usato per creare una nuova risorsa, per eseguire una stored procedure o per inviare una query di Cosmos DB.The POST verb is used for creation of a new resource, for executing a stored procedure or for issuing a Cosmos DB query. Le query sono sempre operazioni di sola lettura senza nessun effetto collaterale.Queries are always read-only operations with no side-effects.

Gli esempi seguenti illustrano un'azione POST per una query dell'API di DocumentDB a fronte di una raccolta contenente i due documenti di esempio esaminati finora.The following examples show a POST for a DocumentDB API query made against a collection containing the two sample documents we've reviewed so far. La query ha un semplice filtro sulla proprietà nome JSON.The query has a simple filter on the JSON name property. Si noti l'uso delle intestazioni x-ms-documentdb-isquery e Content-Type application/query+json per indicare che l'operazione è una query.Note the use of the x-ms-documentdb-isquery and Content-Type: application/query+json headers to denote that the operation is a query.

RichiestaRequest

POST https://<REST URI>/docs HTTP/1.1
...
x-ms-documentdb-isquery: True
Content-Type: application/query+json

{      
    "query": "SELECT * FROM Families f WHERE f.id = @familyId",     
    "parameters": [          
        {"name": "@familyId", "value": "AndersenFamily"}         
    ] 
}

RisultatiResults

HTTP/1.1 200 Ok
x-ms-activity-id: 8b4678fa-a947-47d3-8dd3-549a40da6eed
x-ms-item-count: 1
x-ms-request-charge: 0.32

<indented for readability, results highlighted>

{  
   "_rid":"u1NXANcKogE=",
   "Documents":[  
      {  
         "id":"AndersenFamily",
         "lastName":"Andersen",
         "parents":[  
            {  
               "firstName":"Thomas"
            },
            {  
               "firstName":"Mary Kay"
            }
         ],
         "children":[  
            {  
               "firstName":"Henriette Thaulow",
               "gender":"female",
               "grade":5,
               "pets":[  
                  {  
                     "givenName":"Fluffy"
                  }
               ]
            }
         ],
         "address":{  
            "state":"WA",
            "county":"King",
            "city":"seattle"
         },
         "_rid":"u1NXANcKogEcAAAAAAAAAA==",
         "_ts":1407691744,
         "_self":"dbs\/u1NXAA==\/colls\/u1NXANcKogE=\/docs\/u1NXANcKogEcAAAAAAAAAA==\/",
         "_etag":"00002b00-0000-0000-0000-53e7abe00000",
         "_attachments":"_attachments\/"
      }
   ],
   "count":1
}

Il secondo esempio mostra una query più complessa che restituisce più risultati dal join.The second example shows a more complex query that returns multiple results from the join.

RichiestaRequest

POST https://<REST URI>/docs HTTP/1.1
...
x-ms-documentdb-isquery: True
Content-Type: application/query+json

{      
    "query": "SELECT 
                 f.id AS familyName, 
                 c.givenName AS childGivenName, 
                 c.firstName AS childFirstName, 
                 p.givenName AS petName 
              FROM Families f 
              JOIN c IN f.children 
              JOIN p in c.pets",     
    "parameters": [] 
}

RisultatiResults

HTTP/1.1 200 Ok
x-ms-activity-id: 568f34e3-5695-44d3-9b7d-62f8b83e509d
x-ms-item-count: 1
x-ms-request-charge: 7.84

<indented for readability, results highlighted>

{  
   "_rid":"u1NXANcKogE=",
   "Documents":[  
      {  
         "familyName":"AndersenFamily",
         "childFirstName":"Henriette Thaulow",
         "petName":"Fluffy"
      },
      {  
         "familyName":"WakefieldFamily",
         "childGivenName":"Jesse",
         "petName":"Goofy"
      },
      {  
         "familyName":"WakefieldFamily",
         "childGivenName":"Jesse",
         "petName":"Shadow"
      }
   ],
   "count":3
}

Se il numero di risultati di una query supera le dimensioni di una singola pagina, l'API REST restituisce un token di continuazione attraverso l'intestazione di risposta x-ms-continuation-token .If a query's results cannot fit within a single page of results, then the REST API returns a continuation token through the x-ms-continuation-token response header. I client possono impaginare i risultati includendo l'intestazione nei risultati successivi.Clients can paginate results by including the header in subsequent results. È possibile controllare il numero di risultati per pagina anche attraverso l'intestazione di numero x-ms-max-item-count .The number of results per page can also be controlled through the x-ms-max-item-count number header. Se la query specificata include una funzione di aggregazione come COUNT, la pagina di query può restituire un valore parzialmente aggregato nella pagina dei risultati.If the specified query has an aggregation function like COUNT, then the query page may return a partially aggregated value over the page of results. I client devono eseguire un'aggregazione di secondo livello su questi risultati per ottenere i risultati finali, ad esempio sommare i conteggi restituiti nelle singole pagine per ottenere il conteggio totale.The clients must perform a second-level aggregation over these results to produce the final results, for example, sum over the counts returned in the individual pages to return the total count.

Per gestire i criteri di coerenza dei dati per le query, usare l'intestazione x-ms-consistency-level come tutte le richieste dell'API REST.To manage the data consistency policy for queries, use the x-ms-consistency-level header like all REST API requests. Ai fini della coerenza della sessione, è necessario anche ripetere l'ultima intestazione cookie x-ms-session-token nella richiesta di query.For session consistency, it is required to also echo the latest x-ms-session-token Cookie header in the query request. I criteri di indicizzazione della raccolta sulla quale è stata eseguita la query possono influenzare anche la coerenza dei risultati della query.The queried collection's indexing policy can also influence the consistency of query results. Con le impostazioni predefinite dei criteri di indicizzazione, per le raccolte l'indice è sempre aggiornato con il contenuto del documento e i risultati della query corrispondono alla coerenza scelta per i dati.With the default indexing policy settings, for collections the index is always current with the document contents and query results match the consistency chosen for data. Se i criteri di indicizzazione vengono ridotti alla modalità differita, le query possono restituire risultati obsoleti.If the indexing policy is relaxed to Lazy, then queries can return stale results. Per altre informazioni, vedere Livelli di coerenza di Azure Cosmos DB.For more information, see Azure Cosmos DB Consistency Levels.

Se i criteri di indicizzazione configurati sulla raccolta non possono supportare la query specificata, il server di Azure Cosmos DB restituisce il codice di errore 400 (Richiesta non valida).If the configured indexing policy on the collection cannot support the specified query, the Azure Cosmos DB server returns 400 "Bad Request". Questo codice viene restituito per le query di intervallo per ricerche hash (uguaglianza) e per i percorsi esplicitamente esclusi dall'indicizzazione.This is returned for range queries against paths configured for hash (equality) lookups, and for paths explicitly excluded from indexing. È possibile specificare l'intestazione x-ms-documentdb-query-enable-scan per consentire alla query di eseguire una scansione quando non è disponibile un indice.The x-ms-documentdb-query-enable-scan header can be specified to allow the query to perform a scan when an index is not available.

È possibile ottenere metriche dettagliate sull'esecuzione di query impostando l'intestazione x-ms-documentdb-populatequerymetrics su True.You can get detailed metrics on query execution by setting x-ms-documentdb-populatequerymetrics header to True. Per altre informazioni, vedere metriche di query SQL per l'API Azure Cosmos DB DocumentDB.For more information, see SQL query metrics for Azure Cosmos DB DocumentDB API.

C# (.NET) SDKC# (.NET) SDK

.NET SDK supporta l'esecuzione di query LINQ ed SQL.The .NET SDK supports both LINQ and SQL querying. Nell'esempio seguente viene illustrato come eseguire la semplice query di filtro introdotta in precedenza in questo documento.The following example shows how to perform the simple filter query introduced earlier in this document.

foreach (var family in client.CreateDocumentQuery(collectionLink, 
    "SELECT * FROM Families f WHERE f.id = \"AndersenFamily\""))
{
    Console.WriteLine("\tRead {0} from SQL", family);
}

SqlQuerySpec query = new SqlQuerySpec("SELECT * FROM Families f WHERE f.id = @familyId");
query.Parameters = new SqlParameterCollection();
query.Parameters.Add(new SqlParameter("@familyId", "AndersenFamily"));

foreach (var family in client.CreateDocumentQuery(collectionLink, query))
{
    Console.WriteLine("\tRead {0} from parameterized SQL", family);
}

foreach (var family in (
    from f in client.CreateDocumentQuery(collectionLink)
    where f.Id == "AndersenFamily"
    select f))
{
    Console.WriteLine("\tRead {0} from LINQ query", family);
}

foreach (var family in client.CreateDocumentQuery(collectionLink)
    .Where(f => f.Id == "AndersenFamily")
    .Select(f => f))
{
    Console.WriteLine("\tRead {0} from LINQ lambda", family);
}

In questo esempio vengono confrontate due proprietà per l'uguaglianza all'interno di ciascun documento, usando le proiezioni anonime.This sample compares two properties for equality within each document and uses anonymous projections.

foreach (var family in client.CreateDocumentQuery(collectionLink,
    @"SELECT {""Name"": f.id, ""City"":f.address.city} AS Family 
    FROM Families f 
    WHERE f.address.city = f.address.state"))
{
    Console.WriteLine("\tRead {0} from SQL", family);
}

foreach (var family in (
    from f in client.CreateDocumentQuery<Family>(collectionLink)
    where f.address.city == f.address.state
    select new { Name = f.Id, City = f.address.city }))
{
    Console.WriteLine("\tRead {0} from LINQ query", family);
}

foreach (var family in
    client.CreateDocumentQuery<Family>(collectionLink)
    .Where(f => f.address.city == f.address.state)
    .Select(f => new { Name = f.Id, City = f.address.city }))
{
    Console.WriteLine("\tRead {0} from LINQ lambda", family);
}

Nell'esempio successivo vengono illustrati i join, espressi tramite la clausola SelectMany di LINQ.The next sample shows joins, expressed through LINQ SelectMany.

foreach (var pet in client.CreateDocumentQuery(collectionLink,
      @"SELECT p
        FROM Families f 
             JOIN c IN f.children 
             JOIN p in c.pets 
        WHERE p.givenName = ""Shadow"""))
{
    Console.WriteLine("\tRead {0} from SQL", pet);
}

// Equivalent in Lambda expressions
foreach (var pet in
    client.CreateDocumentQuery<Family>(collectionLink)
    .SelectMany(f => f.children)
    .SelectMany(c => c.pets)
    .Where(p => p.givenName == "Shadow"))
{
    Console.WriteLine("\tRead {0} from LINQ lambda", pet);
}

Il client .NET esegue automaticamente l'iterazione attraverso tutte le pagine dei risultati della query nei blocchi foreach, come sopra illustrato.The .NET client automatically iterates through all the pages of query results in the foreach blocks as shown above. Le opzioni di query presentate nella sezione dell'API REST sono disponibili anche in .NET SDK usando le classi FeedOptions and FeedResponse nel metodo CreateDocumentQuery.The query options introduced in the REST API section are also available in the .NET SDK using the FeedOptions and FeedResponse classes in the CreateDocumentQuery method. È possibile controllare il numero di pagine usando l'impostazione MaxItemCount .The number of pages can be controlled using the MaxItemCount setting.

È anche possibile controllare esplicitamente il paging creando IDocumentQueryable tramite l'oggetto IQueryable, quindi leggendo i valori ResponseContinuationToken e ritrasferendoli come RequestContinuationToken in FeedOptions.You can also explicitly control paging by creating IDocumentQueryable using the IQueryable object, then by reading theResponseContinuationToken values and passing them back as RequestContinuationToken in FeedOptions. EnableScanInQuery per abilitare le analisi quando la query non può essere supportata dai criteri di indicizzazione configurati.EnableScanInQuery can be set to enable scans when the query cannot be supported by the configured indexing policy. Per le raccolte partizionate, è possibile usare PartitionKey per eseguire la query in una partizione singola, anche se Cosmos DB può eseguire l'estrazione automatica dal testo della query, e EnableCrossPartitionQuery per eseguire query che potrebbe essere necessario ripetere in più partizioni.For partitioned collections, you can use PartitionKey to run the query against a single partition (though Cosmos DB can automatically extract this from the query text), and EnableCrossPartitionQuery to run queries that may need to be run against multiple partitions.

Per altri esempi contenenti query, vedere gli esempi relativi a .NET in Azure Cosmos DB.Refer to Azure Cosmos DB .NET samples for more samples containing queries.

API lato server JavaScriptJavaScript server-side API

Cosmos DB offre un modello di programmazione per l'esecuzione di logica dell'applicazione basata su JavaScript direttamente nelle raccolte usando stored procedure e trigger.Cosmos DB provides a programming model for executing JavaScript based application logic directly on the collections using stored procedures and triggers. La logica JavaScript registrata a livello di raccolta può quindi rilasciare operazioni sui documenti della raccolta specifica.The JavaScript logic registered at a collection level can then issue database operations on the operations on the documents of the given collection. Viene quindi eseguito il wrapping di queste operazioni nelle transazioni ACID Ambient.These operations are wrapped in ambient ACID transactions.

L'esempio seguente mostra come usare queryDocuments nell'API del server JavaScript per eseguire query dall'interno di stored procedure e trigger.The following example shows how to use the queryDocuments in the JavaScript server API to make queries from inside stored procedures and triggers.

function businessLogic(name, author) {
    var context = getContext();
    var collectionManager = context.getCollection();
    var collectionLink = collectionManager.getSelfLink()

    // create a new document.
    collectionManager.createDocument(collectionLink,
        { name: name, author: author },
        function (err, documentCreated) {
            if (err) throw new Error(err.message);

            // filter documents by author
            var filterQuery = "SELECT * from root r WHERE r.author = 'George R.'";
            collectionManager.queryDocuments(collectionLink,
                filterQuery,
                function (err, matchingDocuments) {
                    if (err) throw new Error(err.message);
context.getResponse().setBody(matchingDocuments.length);

                    // Replace the author name for all documents that satisfied the query.
                    for (var i = 0; i < matchingDocuments.length; i++) {
                        matchingDocuments[i].author = "George R. R. Martin";
                        // we don't need to execute a callback because they are in parallel
                        collectionManager.replaceDocument(matchingDocuments[i]._self,
                            matchingDocuments[i]);
                    }
                })
        });
}

RiferimentiReferences

  1. Introduzione ad Azure Cosmos DBIntroduction to Azure Cosmos DB
  2. Specifica SQL di Azure Cosmos DBAzure Cosmos DB SQL specification
  3. Esempi relativi a Azure Cosmos DB .NETAzure Cosmos DB .NET samples
  4. Livelli di coerenza di Azure Cosmos DBAzure Cosmos DB Consistency Levels
  5. ANSI SQL 2011 http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=53681ANSI SQL 2011 http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=53681
  6. JSON http://json.org/JSON http://json.org/
  7. Specifiche Javascript http://www.ecma-international.org/publications/standards/Ecma-262.htmJavascript Specification http://www.ecma-international.org/publications/standards/Ecma-262.htm
  8. LINQ http://msdn.microsoft.com/library/bb308959.aspxLINQ http://msdn.microsoft.com/library/bb308959.aspx
  9. Tecniche di valutazione delle query per database di grandi dimensioni http://dl.acm.org/citation.cfm?id=152611Query evaluation techniques for large databases http://dl.acm.org/citation.cfm?id=152611
  10. Query Processing in Parallel Relational Database Systems, IEEE Computer Society Press, 1994Query Processing in Parallel Relational Database Systems, IEEE Computer Society Press, 1994
  11. Lu, Ooi, Tan, Query Processing in Parallel Relational Database Systems, IEEE Computer Society Press, 1994.Lu, Ooi, Tan, Query Processing in Parallel Relational Database Systems, IEEE Computer Society Press, 1994.
  12. Christopher Olston, Benjamin Reed, Utkarsh Srivastava, Ravi Kumar, Andrew Tomkins: Pig Latin: un linguaggio non così estraneo per l'elaborazione dati, SIGMOD 2008.Christopher Olston, Benjamin Reed, Utkarsh Srivastava, Ravi Kumar, Andrew Tomkins: Pig Latin: A Not-So-Foreign Language for Data Processing, SIGMOD 2008.
  13. G.G. Graefe.Graefe. The Cascades framework for query optimization.The Cascades framework for query optimization. IEEE Data Eng.IEEE Data Eng. Bull., 18(3): 1995.Bull., 18(3): 1995.