Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
NoSQL's biggest lie: SQL never went away!
Martin Esmann
Developer Advocate, Couchbase
1
Let’s  do  something  unspectacular
2
©2014  Couchbase  Inc.
A  query
3
SELECT * FROM `travel-sample`
WHERE type = ‘airline’
AND country = ‘United Kingdom’;
©2014  Couchbase  Inc.
A  query
4
Did  I  say  unspectacular?
5
©2014  Couchbase  Inc.
That  was  JSON
6
So,  what  did  we  do?
7
©2014  Couchbase  Inc.
We  put  the  SQL  back  into  NoSQL
8
But  first,  let’s  take  a  step  back
9
©2014  Couchbase  Inc.
NoSQL?
10
Polyglot	
  persistence	
  is	
  “…using	
  multiple	
  data	
  
storage	
  technologies,...
©2014  Couchbase  Inc.
Types  of  NoSQL  database
11
By	
  Schumi4ever	
  (Own	
  work)	
  [CC	
  BY-­‐SA	
  3.0	
  
(http...
©2014  Couchbase  Inc.
Key  value
12
Email: martin@couchbase.comemail:email: {
“personal”: “martin.esmann@hotmail.com”,
“w...
©2014  Couchbase  Inc.
London
matthew@couchbase.com
james@couchbase.com
laura@couchbase.com
tom@couchbase.com
david@couchb...
©2014  Couchbase  Inc.
Document
14
London
matthew@couchbase.com
james@couchbase.com
laura@couchbase.com
Developer Advocacy...
©2014  Couchbase  Inc.
And  the  others
15
Context  is  all
16
©2014  Couchbase  Inc.
There's  always  a  trade-­‐off
17
• Offload	
  from	
  some	
  other	
  data	
  store	
  (i.e.	
  ...
Where  Couchbase comes  in
18
©2014  Couchbase  Inc.
Couchbase Server  4.0
19
High	
  availability	
  
cache
Key-­‐value	
  
store
Document	
  
database...
N1QL:  SQL  for  JSON
20
©2014  Couchbase  Inc.
A  user  profile  as  JSON
21
How  do  we  query  that?
22
©2014  Couchbase  Inc.
Querying  the  JSON  profile
23
• Look-­‐up	
  documents:	
  i.e.	
  manual	
  secondary	
  indexin...
©2014  Couchbase  Inc.
Manual  2i
24
©2014  Couchbase  Inc.
Automatic  2i:  views
25
©2014  Couchbase  Inc.
N1QL
26
©2014  Couchbase  Inc.
SELECT
27
SELECT	
  ...
©2014  Couchbase  Inc.
SELECT
28
SELECT 1 + 1;
{	
  	
  	
  	
  
"requestID":	
  "3ccebac7-­‐341a-­‐4c31-­‐a2c5-­‐b46aaed5...
©2014  Couchbase  Inc.
SELECT  COUNT
29
SELECT COUNT(*) FROM `default`
WHERE office = "London";
{
"requestID": "6e733000-a...
©2014  Couchbase  Inc.
SELECT email FROM `default`
WHERE office = "London";
SELECT
30
©2014  Couchbase  Inc.
SELECT email FROM `default`
WHERE office = "London"
AND team = "Developer Advocacy";
SELECT
31
©2014  Couchbase  Inc.
SELECT email FROM `default`
WHERE office = "London"
AND team != "Developer Advocacy";
SELECT
32
But  this  is  JSON
33
©2014  Couchbase  Inc.
SELECT conferences[0].name
AS event_name FROM `default`;
ARRAY  ELEMENTS
34
©2014  Couchbase  Inc.
SELECT DISTINCT
conferences[0].name
AS event_name FROM `default`;
DISTINCT  ARRAY  ELEMENTS
35
©2014  Couchbase  Inc.
SELECT DISTINCT
conferences[0].name
AS event_name FROM `default`
WHERE conferences
IS NOT MISSING;
...
©2014  Couchbase  Inc.
SELECT email AS person,
conferences[0].name AS event
FROM `default`
WHERE ANY event in conferences
...
What's  going  on  underneath?
38
©2014  Couchbase  Inc.
EXPLAIN SELECT email AS person,
conferences[0].name AS event
FROM `default`
WHERE ANY event in conf...
Is  N1QL  read-­‐only?
40
©2014  Couchbase  Inc.
Updating  and  deleting
41
• DELETE:	
  provide	
  the	
  key	
  to	
  delete	
  the	
  document
• ...
©2014  Couchbase  Inc.
UPDATE
42
©2014  Couchbase  Inc.
DELETE
43
A  larger  data-­‐set:  travel-­‐sample
44
©2014  Couchbase  Inc.
TRAVEL  SAMPLE  DATA
45
©2014  Couchbase  Inc.
travel-­‐sample
46
©2014  Couchbase  Inc.
CREATE  PRIMARY  INDEX
47
CREATE PRIMARY INDEX
ON `travel-sample`
USING GSI;
©2014  Couchbase  Inc.
SELECT
48
SELECT * FROM `travel-sample`
WHERE type = "airline";
©2014  Couchbase  Inc.
SELECT
49
©2014  Couchbase  Inc.
SELECT
50
SELECT * FROM `travel-sample`
WHERE type = "airline"
AND country = "United States";
©2014  Couchbase  Inc.
SELECT
51
Indexes
52
©2014  Couchbase  Inc.
CREATE  INDEX
53
CREATE INDEX airline
ON `travel-sample`(type)
WHERE type = "airline"
USING GSI;
JOINs
54
©2014  Couchbase  Inc.
JOINs
55
• Retrieve	
  data	
  from	
  two	
  documents	
  in	
  a	
  single	
  SELECT
• Join	
  wi...
©2014  Couchbase  Inc.
A  SIMPLE  JOIN
56
SELECT * FROM `travel-sample` r
JOIN `travel-sample` a
ON KEYS r.airlineid
WHERE...
©2014  Couchbase  Inc.
WHO  FLIES  LHR-­‐>SFO?
57
SELECT DISTINCT a.name FROM
`travel-sample` r
JOIN `travel-sample` a
ON ...
©2014  Couchbase  Inc.
UNNEST
58
• Breaks	
  out	
  nested	
  JSON	
  from	
  the	
  results
©2014  Couchbase  Inc.
SOMETHING  USEFUL
59
SELECT a.name, s.flight, s.utc, r.sourceairport,
r.destinationairport, r.equip...
N1QL  vs  View’s
60
©2014  Couchbase  Inc.
N1QL  and  views
61
N1QL Views
Ad-hoc querying Predictable queries
JSON in and JSON out Number crun...
Multi-­‐dimensional  scaling
62
©2014  Couchbase  Inc.
Scaling  out
63
Horizontal  scaling
▪ Partitions  a  dataset  onto  one  or  more  homogenous  node...
©2014  Couchbase  Inc.
What  is  Multi-­‐Dimensional  Scalability?  
MDS  is  the  architecture  that  enables  independen...
©2014  Couchbase  Inc.
Multi-­‐dimensional  scaling
65
Isolated  Service  for  minimized  interference
▪ Independent  “zon...
©2014  Couchbase  Inc.
Multi-­‐dimensional  scaling
66
Independent  scalability  for  the  best  computational  capacity  ...
Geospatial  querying
67
©2014  Couchbase  Inc.
Geospatial  views
68
• Experimental	
  in	
  3.0,	
  now	
  GA	
  in	
  4.0
• Performance	
  and	
 ...
What  else  is  in  Couchbase Server  4.0?
69
©2014  Couchbase  Inc.
Other  new  things  in  Couchbase Server  4.0
70
• ForestDB:	
  GSIs	
  are	
  stored	
  with	
  a	...
Developers?
SDK  support  for  N1QL!
71
©2014  Couchbase  Inc.
.NET SDK: Connection
72
//  Option  1:  Create  Cluster  and  open  bucket  
var cluster  =  new Cl...
©2014  Couchbase  Inc.
.NET SDK: Client Configuration
73
//  Cluster  Configuration
var config =  new ClientConfiguration
...
©2014  Couchbase  Inc.
.NET SDK: Basic Operations
74
//  Create   document   (dynamic)
var doc  =  new Document<dynamic>
{...
©2014  Couchbase  Inc.
.NET SDK: N1QL Query (raw)
75
//  Create  Query  Request.  Raw  API  request
var query  =  QueryReq...
©2014  Couchbase  Inc.
.NET SDK: N1QL Query (Linq2Couchbase)
76
//  Lambda  syntax
var result  =  ClusterHelper.GetBucket(...
©2014  Couchbase  Inc.
.NET SDK: N1QL Query (Linq2Couchbase)
77
//  Query  syntax
var query  =  
from beer  in QueryFactor...
https://github.com/couchbaselabs/N1QL-­‐Intro-­‐dotNET-­‐
Supplement-­‐Demo-­‐code
Next Steps
Couchbase Developer Portal
developer.couchbase.com
80
Forums
http://forums.couchbase.com
81
Thanks for listening!
Nächste SlideShare
Wird geladen in …5
×

NoSQL's biggest lie: SQL never went away - Martin Esmann

702 Aufrufe

Veröffentlicht am

NoSQL databases threw out SQL for querying, while their authors focused on solving problems on scale, speed and availability. The trouble is, the need for rich query never went away. Neither did SQL; it was only resting. Today, non-relational databases are bringing back SQL-like languages and other query mechanisms to help them integrate with existing data query layers (e.g. Hibernate) and to fit in with the overwhelming weight of database query practice of the past 40 years. In this talk I’ll cover how to query data in Couchbase using a SQL like query language called N1QL (Nickel) from .NET. I will also touch on topics like installing, setup, hosting, cloud, azure and perfomance. Demo's will be in C#, but there are SDK's and API’s for all the major languages, therefor if you don’t have a .NET background you can still use what you learn in your favourite language.

You can also check this version with animations: http://www.slideshare.net/martinesmann/no-sq-lsbiggestliesqlneverwentawaymartinesmann

Veröffentlicht in: Daten & Analysen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

NoSQL's biggest lie: SQL never went away - Martin Esmann

  1. 1. NoSQL's biggest lie: SQL never went away! Martin Esmann Developer Advocate, Couchbase 1
  2. 2. Let’s  do  something  unspectacular 2
  3. 3. ©2014  Couchbase  Inc. A  query 3 SELECT * FROM `travel-sample` WHERE type = ‘airline’ AND country = ‘United Kingdom’;
  4. 4. ©2014  Couchbase  Inc. A  query 4
  5. 5. Did  I  say  unspectacular? 5
  6. 6. ©2014  Couchbase  Inc. That  was  JSON 6
  7. 7. So,  what  did  we  do? 7
  8. 8. ©2014  Couchbase  Inc. We  put  the  SQL  back  into  NoSQL 8
  9. 9. But  first,  let’s  take  a  step  back 9
  10. 10. ©2014  Couchbase  Inc. NoSQL? 10 Polyglot  persistence  is  “…using  multiple  data   storage  technologies,  chosen  based  upon  the   way  data  is  being  used  by  individual   applications.  Why  store  binary  images  in   relational  database,  when  there  are  better   storage  systems?”   Martin  Fowler  and  Pramod Sadalage
  11. 11. ©2014  Couchbase  Inc. Types  of  NoSQL  database 11 By  Schumi4ever  (Own  work)  [CC  BY-­‐SA  3.0   (http://creativecommons.org/licenses/by-­‐sa/3.0)],  via  Wikimedia  Commons
  12. 12. ©2014  Couchbase  Inc. Key  value 12 Email: martin@couchbase.comemail:email: { “personal”: “martin.esmann@hotmail.com”, “work”: “martin@couchbase.com” }
  13. 13. ©2014  Couchbase  Inc. London matthew@couchbase.com james@couchbase.com laura@couchbase.com tom@couchbase.com david@couchbase.com greg@couchbase.com Document 13 Developer Advocacy matthew@couchbase.com james@couchbase.com laura@couchbase.com laurent@couchbase.com martin@couchbase.com matt@couchbase.com nic@couchbase.com will@couchbase.com martin@couchbase.com: { "city": ”Copenhagen", "glasses": false, "team": "Developer Advocacy", "music": ”Electronic!" }
  14. 14. ©2014  Couchbase  Inc. Document 14 London matthew@couchbase.com james@couchbase.com laura@couchbase.com Developer Advocacy matthew@couchbase.com james@couchbase.com laura@couchbase.com London and Developer Advocacy matthew@couchbase.com james@couchbase.com laura@couchbase.com
  15. 15. ©2014  Couchbase  Inc. And  the  others 15
  16. 16. Context  is  all 16
  17. 17. ©2014  Couchbase  Inc. There's  always  a  trade-­‐off 17 • Offload  from  some  other  data  store  (i.e.  caching) • Computation  offload • Speed • Scalability • Availability • Flexibility  in  what  you  store • Query  flexibility
  18. 18. Where  Couchbase comes  in 18
  19. 19. ©2014  Couchbase  Inc. Couchbase Server  4.0 19 High  availability   cache Key-­‐value   store Document   database N1QL SQL-­‐like  query   for  JSON
  20. 20. N1QL:  SQL  for  JSON 20
  21. 21. ©2014  Couchbase  Inc. A  user  profile  as  JSON 21
  22. 22. How  do  we  query  that? 22
  23. 23. ©2014  Couchbase  Inc. Querying  the  JSON  profile 23 • Look-­‐up  documents:  i.e.  manual  secondary  indexing  (2i) • Couchbase views:  i.e.  automated  secondary  indexing  (2i) • N1QL
  24. 24. ©2014  Couchbase  Inc. Manual  2i 24
  25. 25. ©2014  Couchbase  Inc. Automatic  2i:  views 25
  26. 26. ©2014  Couchbase  Inc. N1QL 26
  27. 27. ©2014  Couchbase  Inc. SELECT 27 SELECT  ...
  28. 28. ©2014  Couchbase  Inc. SELECT 28 SELECT 1 + 1; {         "requestID":  "3ccebac7-­‐341a-­‐4c31-­‐a2c5-­‐b46aaed54356",       "signature":  {                 "$1":  "number"         },         "results":  [               {                        "$1":  2                 }         ],         "status":  "success",         "metrics":  {                 "elapsedTime":  "31.826219ms",                 "executionTime":  "29.800616ms",                 "resultCount":  1,                 "resultSize":  31         } }
  29. 29. ©2014  Couchbase  Inc. SELECT  COUNT 29 SELECT COUNT(*) FROM `default` WHERE office = "London"; { "requestID": "6e733000-ac83-44ba-95a7-9b012e9c553d", "signature": { "$1": "number" }, "results": [ { "$1": 6 } ], "status": "success", "metrics": { "elapsedTime": "18.603124ms", "executionTime": "18.327696ms", "resultCount": 1, "resultSize": 31 } }
  30. 30. ©2014  Couchbase  Inc. SELECT email FROM `default` WHERE office = "London"; SELECT 30
  31. 31. ©2014  Couchbase  Inc. SELECT email FROM `default` WHERE office = "London" AND team = "Developer Advocacy"; SELECT 31
  32. 32. ©2014  Couchbase  Inc. SELECT email FROM `default` WHERE office = "London" AND team != "Developer Advocacy"; SELECT 32
  33. 33. But  this  is  JSON 33
  34. 34. ©2014  Couchbase  Inc. SELECT conferences[0].name AS event_name FROM `default`; ARRAY  ELEMENTS 34
  35. 35. ©2014  Couchbase  Inc. SELECT DISTINCT conferences[0].name AS event_name FROM `default`; DISTINCT  ARRAY  ELEMENTS 35
  36. 36. ©2014  Couchbase  Inc. SELECT DISTINCT conferences[0].name AS event_name FROM `default` WHERE conferences IS NOT MISSING; REMOVE  MISSING  ITEMS 36
  37. 37. ©2014  Couchbase  Inc. SELECT email AS person, conferences[0].name AS event FROM `default` WHERE ANY event in conferences SATISFIES event.name = "Droidcon Sweden" END; WHO  IS  GOING  TO  DROIDCON  SWEDEN? 37
  38. 38. What's  going  on  underneath? 38
  39. 39. ©2014  Couchbase  Inc. EXPLAIN SELECT email AS person, conferences[0].name AS event FROM `default` WHERE ANY event in conferences SATISFIES event.name = "Droidcon Sweden" END; EXPLAIN 39
  40. 40. Is  N1QL  read-­‐only? 40
  41. 41. ©2014  Couchbase  Inc. Updating  and  deleting 41 • DELETE:  provide  the  key  to  delete  the  document • INSERT:  provide  a  key  and  some  JSON  to  create  a  new  document • UPSERT:  as  INSERT  but  will  overwrite  existing  docs • UPDATE:  change  individual  values  inside  existing  docs
  42. 42. ©2014  Couchbase  Inc. UPDATE 42
  43. 43. ©2014  Couchbase  Inc. DELETE 43
  44. 44. A  larger  data-­‐set:  travel-­‐sample 44
  45. 45. ©2014  Couchbase  Inc. TRAVEL  SAMPLE  DATA 45
  46. 46. ©2014  Couchbase  Inc. travel-­‐sample 46
  47. 47. ©2014  Couchbase  Inc. CREATE  PRIMARY  INDEX 47 CREATE PRIMARY INDEX ON `travel-sample` USING GSI;
  48. 48. ©2014  Couchbase  Inc. SELECT 48 SELECT * FROM `travel-sample` WHERE type = "airline";
  49. 49. ©2014  Couchbase  Inc. SELECT 49
  50. 50. ©2014  Couchbase  Inc. SELECT 50 SELECT * FROM `travel-sample` WHERE type = "airline" AND country = "United States";
  51. 51. ©2014  Couchbase  Inc. SELECT 51
  52. 52. Indexes 52
  53. 53. ©2014  Couchbase  Inc. CREATE  INDEX 53 CREATE INDEX airline ON `travel-sample`(type) WHERE type = "airline" USING GSI;
  54. 54. JOINs 54
  55. 55. ©2014  Couchbase  Inc. JOINs 55 • Retrieve  data  from  two  documents  in  a  single  SELECT • Join  within  a  keyspace/bucket • Join  across  keyspaces/buckets
  56. 56. ©2014  Couchbase  Inc. A  SIMPLE  JOIN 56 SELECT * FROM `travel-sample` r JOIN `travel-sample` a ON KEYS r.airlineid WHERE r.sourceairport="LHR" AND r.destinationairport = "SFO";
  57. 57. ©2014  Couchbase  Inc. WHO  FLIES  LHR-­‐>SFO? 57 SELECT DISTINCT a.name FROM `travel-sample` r JOIN `travel-sample` a ON KEYS r.airlineid WHERE r.sourceairport="LHR" AND r.destinationairport = "SFO";
  58. 58. ©2014  Couchbase  Inc. UNNEST 58 • Breaks  out  nested  JSON  from  the  results
  59. 59. ©2014  Couchbase  Inc. SOMETHING  USEFUL 59 SELECT a.name, s.flight, s.utc, r.sourceairport, r.destinationairport, r.equipment FROM `travel-sample` r UNNEST r.schedule s JOIN `travel-sample` a ON KEYS r.airlineid WHERE r.sourceairport="LHR" AND r.destinationairport = "SFO" AND s.day=1 ORDER BY s.utc;
  60. 60. N1QL  vs  View’s 60
  61. 61. ©2014  Couchbase  Inc. N1QL  and  views 61 N1QL Views Ad-hoc querying Predictable queries JSON in and JSON out Number crunching Large growth clusters Multi-dimensional/geospatial queries
  62. 62. Multi-­‐dimensional  scaling 62
  63. 63. ©2014  Couchbase  Inc. Scaling  out 63 Horizontal  scaling ▪ Partitions  a  dataset  onto  one  or  more  homogenous  nodes ▪ Each  node  runs  the  same  mixed  workloads ▪ Re-­‐partition  dataset  with  additional  hardware  capacity
  64. 64. ©2014  Couchbase  Inc. What  is  Multi-­‐Dimensional  Scalability?   MDS  is  the  architecture  that  enables  independent  scaling  of  data,  query,  and   indexing  workloads. Multi-­‐dimensional  scaling 64
  65. 65. ©2014  Couchbase  Inc. Multi-­‐dimensional  scaling 65 Isolated  Service  for  minimized  interference ▪ Independent  “zones”  for  query,  index,  and  data  services Minimize  indexing  and  query  overhead  on  core  key-­‐value   operations.
  66. 66. ©2014  Couchbase  Inc. Multi-­‐dimensional  scaling 66 Independent  scalability  for  the  best  computational  capacity   per  service Heavier  indexing  (index  more  fields):   scale  up  index  service  nodes. More  RAM  for  query  processing: scale  up  query  service  nodes.
  67. 67. Geospatial  querying 67
  68. 68. ©2014  Couchbase  Inc. Geospatial  views 68 • Experimental  in  3.0,  now  GA  in  4.0 • Performance  and  stability  improvements • GeoJSON output • Bounding-­‐box   and  range  queries  on   multiple  dimensions
  69. 69. What  else  is  in  Couchbase Server  4.0? 69
  70. 70. ©2014  Couchbase  Inc. Other  new  things  in  Couchbase Server  4.0 70 • ForestDB:  GSIs  are  stored  with  a  new  storage  engine • Filtered  XDCR:  more  efficient  cross-­‐data  centre  replication • Security:  LDAP,  admin  auditing
  71. 71. Developers? SDK  support  for  N1QL! 71
  72. 72. ©2014  Couchbase  Inc. .NET SDK: Connection 72 //  Option  1:  Create  Cluster  and  open  bucket   var cluster  =  new Cluster(config); var bucket  =  cluster.OpenBucket(bucketName); //  Option  2:  ClusterHelper and  open  bucket  (Singleton,  thread  safe  bucket  instance ClusterHelper.Initialize(config); var cluster  =  ClusterHelper.Get(); var bucket  =  ClusterHelper.GetBucket(bucketName); //  Close  connection cluster.CloseBucket(bucket); cluster.Dispose();
  73. 73. ©2014  Couchbase  Inc. .NET SDK: Client Configuration 73 //  Cluster  Configuration var config =  new ClientConfiguration { Servers  =  new List<Uri>  {  new Uri("http://10.211.55.2:8091/pools"),}, UseSsl =  false, BucketConfigs =  new Dictionary<string,  BucketConfiguration> { { "travel-­‐sample",   new BucketConfiguration { BucketName =  "travel-­‐sample", UseSsl =  false, Password  =  "", PoolConfiguration =  new PoolConfiguration { MaxSize =  10, MinSize =  5 } } } } };
  74. 74. ©2014  Couchbase  Inc. .NET SDK: Basic Operations 74 //  Create   document   (dynamic) var doc  =  new Document<dynamic> { Id  =  "doc1", Content   =  new { Id  =  "doc1", Title =  "My Document", Type =  "basic", Pages   =  3 } }; //  update   or  create   document var upsertResult =  await bucket.UpsertAsync<dynamic>(doc); //  Get  document var getResult =  bucket.GetDocument<dynamic>("key1"); //  Delete   document var deleteResult =  await bucket.RemoveAsync<dynamic>(doc); //  Check   if  doc/key   exsists var exsists =  await bucket.ExistsAsync("key1");
  75. 75. ©2014  Couchbase  Inc. .NET SDK: N1QL Query (raw) 75 //  Create  Query  Request.  Raw  API  request var query  =  QueryRequest.Create("SELECT  COUNT(*)  FROM  `travel-­‐sample`  WHERE  type  =  'airline'"); //  Execute  Query.   var response  =  await bucket.QueryAsync<dynamic>(query); //  Convert  result  to  string  for  easy  console  print  out. var result  =  JsonConvert.SerializeObject(response,  Formatting.Indented);
  76. 76. ©2014  Couchbase  Inc. .NET SDK: N1QL Query (Linq2Couchbase) 76 //  Lambda  syntax var result  =  ClusterHelper.GetBucket("beer-­‐sample") .Queryable<Beer>() .Where(a  =>  a.Type ==  "beer") .Select(a  =>  a) .Join( ClusterHelper.GetBucket("beer-­‐sample") .Queryable<Brewery>() .Where(airline  =>  airline.Type ==  "brewery"), innerKey =>  innerKey.BreweryId, outerKey =>  N1Ql.Key(  outerKey),   (inner,outer)  =>  new {  Inner  =    inner,  Outer  =  outer}) .Take(1) .ToList();
  77. 77. ©2014  Couchbase  Inc. .NET SDK: N1QL Query (Linq2Couchbase) 77 //  Query  syntax var query  =   from beer  in QueryFactory.Queryable<Beer>(mockBucket.Object) join breweryGroup in QueryFactory.Queryable<Brewery>(mockBucket.Object) on beer.BreweryId equals N1Ql.Key(breweryGroup)  into bg from brewery  in bg.DefaultIfEmpty() select new {  beer.Name,  beer.Abv,  BreweryName =  brewery.Name };
  78. 78. https://github.com/couchbaselabs/N1QL-­‐Intro-­‐dotNET-­‐ Supplement-­‐Demo-­‐code
  79. 79. Next Steps
  80. 80. Couchbase Developer Portal developer.couchbase.com 80
  81. 81. Forums http://forums.couchbase.com 81
  82. 82. Thanks for listening!

×