diff --git a/modules/cheatsheets/Couchbase-N1QL-CheatSheet.adoc b/modules/cheatsheets/Couchbase-N1QL-CheatSheet.adoc index 0b3cd883e3..19bc083f58 100644 --- a/modules/cheatsheets/Couchbase-N1QL-CheatSheet.adoc +++ b/modules/cheatsheets/Couchbase-N1QL-CheatSheet.adoc @@ -1,27 +1,28 @@ = QUERYING WITH {sqlpp} :author: Couchbase, Inc. :title: Couchbase {sqlpp} Cheatsheet -:revnumber: 2 +:sqlpp: SQL++ +:revnumber: 3 :revdate: {docdate} :source-highlighter: highlight.js :highlightjsdir: highlight :highlightjs-theme: foundation -:stylesheet: asciidoctor-pdf/css/asciidoctor.css;asciidoctor-pdf/css/document.css;cheatsheet.css +:stylesheet: +cheatsheet.css :stylesdir: style :imagesdir: images :description: Created using asciidoctor-pdf.js — https://github.com/Mogztter/asciidoctor-pdf.js image::CB Color w Black.svg[,100] -This cheatsheet uses the dataset found in the online {sqlpp} tutorial at http://query-tutorial.couchbase.com. +This cheatsheet uses the dataset found in the online tutorial at http://query-tutorial.couchbase.com. [[basics]] -== Basics +== BASICS [[basics-select]] === SELECT Statement -[source,sqlpp] +[source,n1ql] ---- SELECT count(*), state FROM customer @@ -36,16 +37,18 @@ The result set is grouped and ordered by state. Output is limited to 5 documents, after skipping the first 5. [[basics-arithmetic]] -=== SIMPLE ARITHMETIC +=== Simple Arithmetic Normalized, rounded, and truncated ratings: -[source,sqlpp] +[source,n1ql] ---- -SELECT -AVG(reviews.rating) / 5 AS normalizedRating, -ROUND((AVG(reviews.rating) / 5), 2) AS roundedRating, -TRUNC((AVG(reviews.rating) / 5), 3) AS truncRating +SELECT AVG(reviews.rating) / 5 +AS normalizedRating, +ROUND((AVG(reviews.rating) / 5), 2) +AS roundedRating, +TRUNC((AVG(reviews.rating) / 5), 3) +AS truncRating FROM reviews AS reviews WHERE reviews.customerId = "customer62" ---- @@ -68,12 +71,12 @@ See the result set for this query below: Try using other aggregation functions like SUM, MIN, and MAX. [[basics-strings]] -=== STRING CONCATENATION AND MATCHING +=== String Concatenation and Matching The || operator concatenates the first and last names to form the full name. The LIKE operator filters customers with email addresses ending in .biz. -[source,sqlpp] +[source,n1ql] ---- SELECT firstName || " " || lastName AS fullName FROM customer @@ -85,7 +88,7 @@ WHERE emailAddress LIKE "%.biz" "results": [ { "fullName": "Joyce Murazik" - }, ... + }, // ... ] ---- @@ -98,19 +101,19 @@ The DISTINCT keyword enables you to remove duplicate results. To count the number of unique customers who have purchased something: -[source,sqlpp] +[source,n1ql] ---- SELECT COUNT( DISTINCT customerId ) FROM purchases ---- [[basics-null-missing]] -=== NULL AND MISSING VALUES +=== NULL and MISSING Values JSON documents can contain NULL values or omit fields entirely. The NULL/MISSING operators let you test for these conditions. -[source,sqlpp] +[source,n1ql] ---- SELECT fname, children FROM tutorial @@ -120,12 +123,12 @@ WHERE children IS NULL Now, try changing IS NULL to IS MISSING. [[basics-indexes]] -=== INDEXES +=== Indexes {sqlpp} uses indexes to perform queries. You can create primary indexes and global secondary indexes. -[source,sqlpp] +[source,n1ql] ---- CREATE INDEX idx ON `customer`(`emailAddress`) ---- @@ -135,18 +138,19 @@ CREATE INDEX idx ON `customer`(`emailAddress`) EXPLAIN shows how a statement will operate. -[source,sqlpp] +[source,n1ql] ---- EXPLAIN ---- [[data]] -== Data Structures +== DATA STRUCTURES [[data-arrays-objects]] -=== ARRAYS AND OBJECTS +=== Arrays and Objects -{sqlpp} supports nested JSON objects where you can use the dot “.” operator to access fields nested inside other objects as well as the bracket [index] to access elements inside an array. +{sqlpp} supports nested JSON arrays and objects. +You can use the dot “.” operator to access fields inside nested objects, and the bracket [index] to access elements inside an array. For example, consider the following object: @@ -165,17 +169,17 @@ ARRAY_APPEND(,) + ARRAY_CONCAT(,) [[data-collections]] -=== COLLECTION EXPRESSIONS +=== Range Predicates -A collection in {sqlpp} is an array-valued subpath or expression. -Collection predicates allow you to test a boolean condition over the elements of a collection. +{sqlpp} provides operators to work with arrays of nested objects. +Range predicates allow you to test a boolean condition over the elements of an array. The ANY operator allows you to search through an array, returning TRUE when at least one match is found. With the EVERY operator, every single element needs to match. To search for purchase orders with a particular item purchased 5 times or more: -[source,sqlpp] +[source,n1ql] ---- SELECT * FROM purchases @@ -185,13 +189,13 @@ WHERE ANY item IN purchases.lineItems SATISFIES item.count >= 5 END Try changing ANY to EVERY. [[data-array-first]] -==== ARRAY and FIRST +=== Range Transformations -To map and filter elements of a collection, you can use the ARRAY and FIRST operators. +To map and filter elements of an array, you can use the ARRAY and FIRST operators. To get an array of products for each purchase order: -[source,sqlpp] +[source,n1ql] ---- SELECT ARRAY item.product FOR item IN purchases.lineItems END @@ -202,7 +206,7 @@ FROM purchases Changing ARRAY to FIRST will produce the first product in each purchase order. [[joins]] -== Joins +== JOINS [[join-nest-unnest]] === JOIN, NEST, and UNNEST @@ -213,7 +217,7 @@ NEST produces a single result for each left-hand input, while the right-hand inp To assemble a complete list of products purchased by a customer: -[source,sqlpp] +[source,n1ql] ---- SELECT c, pr FROM purchases pu @@ -226,7 +230,7 @@ The UNNEST clause allows you to take contents of a nested array and join them wi To list products belonging to a particular category: -[source,sqlpp] +[source,n1ql] ---- SELECT p FROM product p diff --git a/modules/cheatsheets/Couchbase-N1QL-CheatSheet.html b/modules/cheatsheets/Couchbase-N1QL-CheatSheet.html deleted file mode 100644 index e39412673d..0000000000 --- a/modules/cheatsheets/Couchbase-N1QL-CheatSheet.html +++ /dev/null @@ -1,30561 +0,0 @@ - - - -QUERYING WITH SQL++ - - - - - - - - - -
-

QUERYING WITH SQL++

-
- - -
-
-
-
-
-CB Color w Black -
-
-
-

This cheatsheet uses the dataset found in the online SQL++ tutorial at http://query-tutorial.couchbase.com.

-
-
-
-
-

Basics

-
-
-

SELECT Statement

-
-
-
SELECT count(*), state
-FROM customer
-WHERE customer.ccInfo.cardType="discover"
-GROUP BY customer.state
-ORDER BY customer.state
-LIMIT 5 OFFSET 5
-
-
-
-

This query counts the number of customers per state who have a Discover credit card. -The result set is grouped and ordered by state. -Output is limited to 5 documents, after skipping the first 5.

-
-
-
-

SIMPLE ARITHMETIC

-
-

Normalized, rounded, and truncated ratings:

-
-
-
-
SELECT
-AVG(reviews.rating) / 5 AS normalizedRating,
-ROUND((AVG(reviews.rating) / 5), 2) AS roundedRating,
-TRUNC((AVG(reviews.rating) / 5), 3) AS truncRating
-FROM reviews AS reviews
-WHERE reviews.customerId = "customer62"
-
-
-
-

With SQL++, you can use the +, -­, * and / operators. -SQL++ has functions for rounding (ROUND) and truncation (TRUNC). -See the result set for this query below:

-
-
-
-
"results": [
-  {
-    "normalizedRating": 0.65,
-    "roundedRating": 0.65,
-    "truncRating": 0.65
-  }
-]
-
-
-
-

Try using other aggregation functions like SUM, MIN, and MAX.

-
-
-
-

STRING CONCATENATION AND MATCHING

-
-

The || operator concatenates the first and last names to form the full name. -The LIKE operator filters customers with email addresses ending in .biz.

-
-
-
-
SELECT firstName || " " || lastName AS fullName
-FROM customer
-WHERE emailAddress LIKE "%.biz"
-
-
-
-
-
"results": [
-  {
-    "fullName": "Joyce Murazik"
-  }, ...
-]
-
-
-
-

SQL++ also provides string functions such as LOWER, UPPER, SUBSTR, and LENGTH.

-
-
-
-

DISTINCT

-
-

The DISTINCT keyword enables you to remove duplicate results.

-
-
-

To count the number of unique customers who have purchased something:

-
-
-
-
SELECT COUNT( DISTINCT customerId )
-FROM purchases
-
-
-
-
-

NULL AND MISSING VALUES

-
-

JSON documents can contain NULL values or omit fields entirely. -The NULL/MISSING operators let you test for these conditions.

-
-
-
-
SELECT fname, children
-FROM tutorial
-WHERE children IS NULL
-
-
-
-

Now, try changing IS NULL to IS MISSING.

-
-
-
-

INDEXES

-
-

SQL++ uses indexes to perform queries. -You can create primary indexes and global secondary indexes.

-
-
-
-
CREATE INDEX idx ON `customer`(`emailAddress`)
-
-
-
-
-

EXPLAIN

-
-

EXPLAIN shows how a statement will operate.

-
-
-
-
EXPLAIN <Query Statement>
-
-
-
-
-
-
-

Data Structures

-
-
-

ARRAYS AND OBJECTS

-
-

SQL++ supports nested JSON objects where you can use the dot “.” operator to access fields nested inside other objects as well as the bracket [index] to access elements inside an array.

-
-
-

For example, consider the following object:

-
-
-
-
{ "address" : { "city": "Toronto"}, "revision": [2014] }
-
-
-
-

address.city will return "Toronto" and revision[0] will return 2014.

-
-
-

These are some of the additional array functions:

-
-
-

ARRAY_LENGTH(<array>)
-ARRAY_PREPEND(<value>,<array>)
-ARRAY_APPEND(<array>,<value>)
-ARRAY_CONCAT(<array1>,<array2>)

-
-
-
-

COLLECTION EXPRESSIONS

-
-

A collection in SQL++ is an array-valued subpath or expression. -Collection predicates allow you to test a boolean condition over the elements of a collection.

-
-
-

The ANY operator allows you to search through an array, returning TRUE when at least one match is found. -With the EVERY operator, every single element needs to match.

-
-
-

To search for purchase orders with a particular item purchased 5 times or more:

-
-
-
-
SELECT *
-FROM purchases
-WHERE ANY item IN purchases.lineItems SATISFIES item.count >= 5 END
-
-
-
-

Try changing ANY to EVERY.

-
-
-

ARRAY and FIRST

-
-

To map and filter elements of a collection, you can use the ARRAY and FIRST operators.

-
-
-

To get an array of products for each purchase order:

-
-
-
-
SELECT ARRAY item.product
-FOR item IN purchases.lineItems END
-AS product_ids
-FROM purchases
-
-
-
-

Changing ARRAY to FIRST will produce the first product in each purchase order.

-
-
-
-
-
-
-

Joins

-
-
-

JOIN, NEST, and UNNEST

-
-

A JOIN in SQL++ is similar to SQL; a single result is produced for each matching left and right-hand input.

-
-
-

NEST produces a single result for each left-hand input, while the right-hand input is collected and nested into a single array-valued field in the result.

-
-
-

To assemble a complete list of products purchased by a customer:

-
-
-
-
SELECT c, pr
-FROM purchases pu
-JOIN customer c ON KEYS pu.customerId
-NEST product pr ON KEYS ARRAY li.product FOR li IN pu.lineItems END
-WHERE pu.customerId = "customer1"
-
-
-
-

The UNNEST clause allows you to take contents of a nested array and join them with the parent object.

-
-
-

To list products belonging to a particular category:

-
-
-
-
SELECT p
-FROM product p
-UNNEST p.categories AS category
-WHERE category= "Appliances"
-
-
-
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/modules/cheatsheets/Couchbase-N1QL-CheatSheet.pdf b/modules/cheatsheets/Couchbase-N1QL-CheatSheet.pdf deleted file mode 100644 index daeffac225..0000000000 Binary files a/modules/cheatsheets/Couchbase-N1QL-CheatSheet.pdf and /dev/null differ diff --git a/modules/cheatsheets/attachments/Couchbase-N1QL-CheatSheet.pdf b/modules/cheatsheets/attachments/Couchbase-N1QL-CheatSheet.pdf new file mode 100644 index 0000000000..7d88994999 Binary files /dev/null and b/modules/cheatsheets/attachments/Couchbase-N1QL-CheatSheet.pdf differ diff --git a/modules/cheatsheets/style/cheatsheet.css b/modules/cheatsheets/style/cheatsheet.css index 96317443e3..28440833c2 100644 --- a/modules/cheatsheets/style/cheatsheet.css +++ b/modules/cheatsheets/style/cheatsheet.css @@ -4,22 +4,96 @@ @page { size: letter; + margin-top: 0.5in; + margin-right: 0.5in; + margin-bottom: 0in; + margin-left: 0.5in; + @top-left-corner { + content: normal; + margin: none; + border: none; + } + @top-left { + content: normal; + margin: none; + border: none; + } + @top-center { + content: normal; + margin: none; + border: none; + } + @top-right { + content: normal; + margin: none; + border: none; + } + @top-right-corner { + content: normal; + margin: none; + border: none; + } + @left-top { + content: normal; + margin: none; + border: none; + } + @left-middle { + content: normal; + margin: none; + border: none; + } + @left-bottom { + content: normal; + margin: none; + border: none; + } + @right-top { + content: normal; + margin: none; + border: none; + } + @right-middle { + content: normal; + margin: none; + border: none; + } + @right-bottom { + content: normal; + margin: none; + border: none; + } + @bottom-left-corner { + content: normal !important; + margin: none; + border: none !important; + } + @bottom-left { + content: normal !important; + margin: none; + border: none !important; + } + @bottom-center { + content: normal !important; + margin: none; + border: none !important; + } + @bottom-right { + content: normal !important; + margin: none; + border: none !important; + } + @bottom-right-corner { + content: normal !important; + margin: none; + border: none !important; + } } body { font-family: 'Open Sans', sans-serif; } -:root, -.pagedjs_page { - --pagedjs-pagebox-width: 8.5in; - --pagedjs-pagebox-height: 11in; - --pagedjs-margin-top: 0.5in; - --pagedjs-margin-right: 0.5in; - --pagedjs-margin-bottom: 0.25in; - --pagedjs-margin-left: 0.5in; -} - .pagedjs_page_content { column-count: 2 !important; column-width: 3in !important; @@ -33,15 +107,10 @@ div.content { } /* No margin for headings at top of page */ +/* FIXME: Make this work for all headings after a page break */ -div.title-document > h1, -div.pagedjs_page_content div.sect1:first-of-type > h2, -div.pagedjs_page_content div.sect2:first-of-type > h3, -div.pagedjs_page_content div.sect3:first-of-type > h4, -div.pagedjs_page_content div.sect4:first-of-type > h5, -div.pagedjs_page_content div.sect5:first-of-type > h6 { - margin-top: 0; - border-top: none; +div.sectionbody[data-split-from] div.sect2 > h3 { + margin-top: 0 !important; } /* Heading sizes scaled in major thirds, Couchbase red */ @@ -80,9 +149,7 @@ h4 { break-inside: avoid; } -.sect3, -.sect4, -.sect5 { +.sect2 { break-inside: avoid; } @@ -100,16 +167,6 @@ h6, break-before: avoid; } -/* Hide empty split divs at the end of a page */ - -.sect1:empty, -.sect2:empty, -.sect3:empty, -.sect4:empty, -.sect5:empty { - display: none; -} - /* Text alignment */ div.title-document, diff --git a/modules/getting-started/pages/try-a-query.adoc b/modules/getting-started/pages/try-a-query.adoc index 56b2d0ef7e..50b059abaa 100644 --- a/modules/getting-started/pages/try-a-query.adoc +++ b/modules/getting-started/pages/try-a-query.adoc @@ -272,7 +272,7 @@ xref:scala-sdk:howtos:n1ql-queries-with-sdk.adoc[Scala] The modules are self-contained and let you modify and run sample queries. The tutorial covers `SELECT` statements in detail, including examples of `JOIN`, `NEST`, `GROUP BY`, and other typical clauses. -* http://docs.couchbase.com/files/Couchbase-N1QL-CheatSheet.pdf[N1QL Cheat Sheet^]: Provides a concise summary of the basic syntax elements of N1QL. +* xref:cheatsheets:attachment$Couchbase-N1QL-CheatSheet.pdf[N1QL Cheat Sheet]: Provides a concise summary of the basic syntax elements of N1QL. Print it out and keep it on your desk where it'll be handy for quick reference. * xref:n1ql:n1ql-language-reference/index.adoc[N1QL Language Reference]: Describes the N1QL language structure, including syntax and usage. diff --git a/modules/n1ql/pages/tutorial.adoc b/modules/n1ql/pages/tutorial.adoc index 9157cd1040..8d4ee94821 100644 --- a/modules/n1ql/pages/tutorial.adoc +++ b/modules/n1ql/pages/tutorial.adoc @@ -38,4 +38,4 @@ The modules are self-contained and let you modify and run sample queries. The {sqlpp} cheat sheet provides a concise summary of the basic syntax elements of {sqlpp}. -* http://docs.couchbase.com/files/Couchbase-N1QL-CheatSheet.pdf[{sqlpp} Cheat Sheet^] +* xref:cheatsheets:attachment$Couchbase-N1QL-CheatSheet.pdf[{sqlpp} Cheat Sheet]