{"id":5885,"date":"2018-10-11T12:04:19","date_gmt":"2018-10-11T19:04:19","guid":{"rendered":"http:\/\/www.couchbase.com\/blog\/?p=5885"},"modified":"2025-06-13T21:20:30","modified_gmt":"2025-06-14T04:20:30","slug":"a-couchbase-analytics-example-using-the-go-sdk","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/","title":{"rendered":"A Couchbase Analytics Example using the Go SDK"},"content":{"rendered":"<p><span style=\"font-weight: 400\">This post illustrates the use of Couchbase Analytics with the Couchbase Go SDK. Couchbase Analytics is a new service available in Couchbase Server 6.0, you can read more at <a href=\"https:\/\/docs.couchbase.com\/server\/6.0\/analytics\/introduction.html\">https:\/\/docs.couchbase.com\/server\/6.0\/analytics\/introduction.html<\/a>. <\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\">In this post we\u2019re going to use a real world dataset which is big enough to not fit in memory (on my local machine at least). We\u2019ll be using the <\/span><a href=\"https:\/\/data.cityofnewyork.us\/api\/views\/hvrh-b6nb\/rows.csv?accessType=DOWNLOAD\"><span style=\"font-weight: 400\">CSV export<\/span><\/a><span style=\"font-weight: 400\"> of the <\/span><a href=\"https:\/\/data.cityofnewyork.us\/Transportation\/2016-Green-Taxi-Trip-Data\/hvrh-b6nb\"><span style=\"font-weight: 400\">2016 NYC green taxi journey dataset<\/span><\/a><span style=\"font-weight: 400\">. This is a dataset of ~16.4 million records with 23 fields per record. You can follow along and try out the application by cloning the project <\/span><a href=\"https:\/\/github.com\/chvck\/gocb-taxi-analytics\"><span style=\"font-weight: 400\">here<\/span><\/a><span style=\"font-weight: 400\">, or run <span class=\"lang:default decode:true crayon-inline \">go get github.com\/chvck\/gocb-taxi-analytics<\/span>\u00a0<\/span><span style=\"font-weight: 400\">.<\/span><span style=\"font-weight: 400\"> You\u2019ll also need to run <span class=\"lang:default decode:true crayon-inline \">go get .\/&#8230;<\/span>\u00a0<\/span><span style=\"font-weight: 400\">if you\u2019ve git cloned the project.<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\">As this data is a CSV file the first job is to import it. Unfortunately this dataset uses non-standard datetime formats so we need to use a small script to go through and convert them into something more useable. If you\u2019ve cloned <\/span><a href=\"https:\/\/github.com\/chvck\/gocb-taxi-analytics\"><span style=\"font-weight: 400\">the project<\/span><\/a><span style=\"font-weight: 400\"> then you can do this with <\/span><\/p>\n<pre class=\"lang:default decode:true\">go run main.go --reformat --csv \/path\/to\/taxis.csv<\/pre>\n<p><span style=\"font-weight: 400\">This will create a <span class=\"lang:default decode:true crayon-inline \">2016_Green_Taxi_Trip_Data.csv<\/span>\u00a0<\/span><span style=\"font-weight: 400\">\u00a0file in the project directory. I\u2019ve also taken this opportunity to change the CSV headers to make them more JSON friendly and also add a type field always set to green (in case we later wanted to add the yellow taxi dataset too). During the conversion we could have also imported the data but we already have a great tool in <\/span><a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/tools\/cbimport.html\"><span style=\"font-weight: 400\">cbimport<\/span><\/a><span style=\"font-weight: 400\"> that we can use. Create a bucket named <\/span><span style=\"font-weight: 400\">taxis <\/span><span style=\"font-weight: 400\">with full eviction enabled (under Advanced bucket settings &#8211; we won\u2019t be running k\/v operations so k\/v performance does not matter as much in this instance) and then run:<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><\/p>\n<pre class=\"wrap:true lang:default decode:true\">cbimport csv --cluster couchbase:\/\/localhost -u user -p password -b taxis --infer-types -omit-empty -d file:\/\/\/path\/to\/2016_Green_Taxi_Trip_Data.csv -l import.log -g green::%vendorID%::#MONO_INCR#<\/pre>\n<p><span style=\"font-weight: 400\">Each document will have a unique ID like <span class=\"lang:default decode:true crayon-inline \">green::1::1000<\/span>\u00a0. Ordinarily these 2 steps wouldn\u2019t be required as our data would already be held in Couchbase.<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\">Before you can do any work with Couchbase Analytics you have to prepare a dataset to enable you to query the data:<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><\/p>\n<pre class=\"lang:default decode:true \">CREATE DATASET alltaxis ON taxis;<\/pre>\n<p><span style=\"font-weight: 400\">This dataset does require some resources. If you want to experiment with a slightly smaller dataset on a busy laptop, instead, you can make a filtered dataset which will only track a subset of the documents in your bucket:<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><\/p>\n<pre class=\"lang:default decode:true\">CREATE DATASET alltaxis ON taxis WHERE `vendorID` = 1;<\/pre>\n<p><span style=\"font-weight: 400\">This will you give you a dataset of a little over 3 million documents.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Once you\u2019ve created one of the datasets then you need to initialise it by activating dataset processing with:<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><\/p>\n<pre class=\"lang:default decode:true \">CONNECT LINK Local;<\/pre>\n<p><span style=\"font-weight: 400\">This will begin populating the dataset that you&#8217;ve just created. You can see the progress in the UI in the right hand Datasets column, below the dataset name. You can continue to work with the dataset whilst it\u2019s building but you\u2019ll see different results each time that you run a query and execution may be a little slower.<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\">As we\u2019re going to be doing some data analysis it\u2019s worth working out a couple of things to investigate. I think that a good starting point would be to know the number of taxi rides across the year and to be able to apply various filters to see things like tips against fares.<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\">The base that we will use for our queries is:<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><\/p>\n<pre class=\"lang:default decode:true \">SELECT DATE_PART_STR(pickupDate, \"month\") AS period, COUNT(*) as count FROM alltaxis GROUP BY DATE_PART_STR(pickupDate, \"month\") ORDER BY period;\r\n<\/pre>\n<p><span style=\"font-weight: 400\">This query is extracting the month as a number (1-12) from the <\/span><span style=\"font-weight: 400\">pickupDate<\/span><span style=\"font-weight: 400\"> field and displaying the number of journeys against the month. What we can see by running this query is that March has the most journeys and that November has the least journeys. There is also a downward trend across the year. I had expected Summer to have fewer journeys than the rest of the year so I\u2019ve learned something already!<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\">This query takes about 24s for the full dataset on my machine. Running the same against the operational query service (often just referred to as N1QL, but that\u2019s the language) with only a primary index times out from the query console (600s). We can see that for ad hoc queries on large datasets Couchbase Analytics is a good option, complementing the operational N1QL query service .<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Querying from a Golang Application<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Now that we\u2019ve setup and tested that our Analytics dataset works we can use it via the Go SDK. In the <\/span><span style=\"font-weight: 400\">runServer <\/span><span style=\"font-weight: 400\">function we have:<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><\/p>\n<pre class=\"lang:go decode:true \">var err error\r\ncluster, err = gocb.Connect(cbConnStr)\r\nif err != nil {\r\n\tpanic(\"Error connecting to cluster:\" + err.Error())\r\n}\r\n\r\ncluster.Authenticate(gocb.PasswordAuthenticator{\r\n\tUsername: cbUsername,\r\n\tPassword: cbPassword,\r\n})\r\n\r\n\t\r\n_, err = cluster.OpenBucket(\"taxis\", \"\")\r\nif err != nil {\r\n\tlog.Fatal(err)\r\n}\r\n\r\nstop := make(chan os.Signal, 1)\r\n\r\n\/\/ Stop the server on interrupt\r\nsignal.Notify(stop, os.Interrupt)\r\n\r\nsrv, err := run()\r\nif err != nil {\r\n\tlog.Fatal(err)\r\n}\r\n\r\nfmt.Println(\"Server running on\", srv.Addr)\r\n&lt;-stop\r\nlog.Println(\"Stopping server\")\r\nsrv.Shutdown(nil)<\/pre>\n<p><span style=\"font-weight: 400\">This creates a connection to Couchbase Server and authenticates using the username and password (these properties can be customised by modifying the properties at the top of the main.go). Next we open a connection to our bucket. The remainder of the function is handling the web server. We create a channel listening to the interrupt signal and when that triggers we gracefully shutdown the http server.<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><span style=\"font-weight: 400\">It\u2019s difficult to visualise and filter this data on the command line so in the linked codebase we\u2019ve added a simple graphical UI. The web server serves up the index page and exposes a single endpoint for retrieving dynamic data. Once again, to run this use <span class=\"lang:default decode:true crayon-inline \">go run main.go<\/span>\u00a0<\/span><span style=\"font-weight: 400\">\u00a0<\/span><span style=\"font-weight: 400\">and you can access the frontend from <span class=\"lang:default decode:true crayon-inline \">https:\/\/localhost:8010<\/span>\u00a0<\/span><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Our handler for the dynamic data endpoint looks like this:<\/span><\/p>\n<pre class=\"lang:go decode:true \">func requestHandler(w http.ResponseWriter, r *http.Request) {\r\n\topts, err := processQueryString(r.URL.Query())\r\n\tif err != nil {\r\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\r\n\t\treturn\r\n\t}\r\n\r\n\tq := `select DATE_PART_STR(pickupDate, \"%s\") AS period, %s as aggregate FROM alltaxis`\r\n\tq += ` %s GROUP BY DATE_PART_STR(pickupDate, \"%s\") ORDER BY period;`\r\n\tq = fmt.Sprintf(q, opts.Period, opts.Aggregate, opts.Where, opts.Period)\r\n\tquery := gocb.NewAnalyticsQuery(q)\r\n\r\n\tresults, err := cluster.ExecuteAnalyticsQuery(query, opts.Params)\r\n\tif err != nil {\r\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\r\n\t\treturn\r\n\t}\r\n\r\n\tdata, err := processResults(results)\r\n\tif err != nil {\r\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\r\n\t\treturn\r\n\t}\r\n\r\n\tdata.Where = fmt.Sprintf(\"%s %s, %v\", opts.Aggregate, opts.Where, opts.Params)\r\n\tdata.Query = fmt.Sprintf(\"query = %s, params = %v\", q, opts.Params)\r\n\tdata.TimeTaken = results.Metrics().ExecutionTime.Nanoseconds()\r\n\tjs, err := json.Marshal(*data)\r\n\tif err != nil {\r\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\r\n\t\treturn\r\n\t}\r\n\r\n\tw.WriteHeader(200)\r\n\tw.Header().Set(\"Content-Type\", \"application\/json\")\r\n\tw.Write(js)\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">What we can see here is that we process the query string to extract the where (plus parameters, more on that below), aggregate and time period. We create our query as a string, incorporating these properties and then use <span class=\"lang:default decode:true crayon-inline \">NewAnalyticsQuery<\/span>\u00a0<\/span><span style=\"font-weight: 400\">\u00a0<\/span><span style=\"font-weight: 400\">to create an <span class=\"lang:default decode:true crayon-inline \">AnalyticsQuery<\/span>\u00a0<\/span><span style=\"font-weight: 400\">. To execute the query it is passed into <span class=\"lang:default decode:true crayon-inline \">cluster.ExecuteAnalyticsQuery<\/span>\u00a0<\/span><span style=\"font-weight: 400\">. <\/span><span style=\"font-weight: 400\">The results are then processed by <span class=\"lang:default decode:true crayon-inline \">processResults<\/span>\u00a0<\/span><span style=\"font-weight: 400\">\u00a0before sending the http response. <span class=\"lang:default decode:true crayon-inline \">Where<\/span>\u00a0<\/span><span style=\"font-weight: 400\">,\u00a0<span class=\"lang:default decode:true crayon-inline \">TimeTaken<\/span>\u00a0 <\/span><span style=\"font-weight: 400\">and\u00a0<\/span><span style=\"font-weight: 400\"> <span class=\"lang:default decode:true crayon-inline \">Query<\/span>\u00a0<\/span><span style=\"font-weight: 400\">\u00a0properties are also added to the response so that we can display what\u2019s been queried in the frontend. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Let\u2019s look at each of these parts in a bit more detail. The where and aggregate parameters are passed from the frontend already formatted correctly. The query string could look something like <\/span><\/p>\n<p><span class=\"lang:default decode:true crayon-inline \">?period=hour&amp;month=5&amp;day=14&amp;aggregate=count(*)&amp;where=fareAmount,&gt;,15&amp;where=tip,&lt;,1<\/span><\/p>\n<p><span style=\"font-weight: 400\">What\u2019s happening here is that period dictates the granularity of the query: a day, month or the entire year. For the case where we\u2019re looking at a day we need to know which day and which month too, the month and day parameters will be present or not present depending on the period. The aggregate is the operation and the field to apply the operation to. Instead of <span class=\"lang:default decode:true crayon-inline \">count(*)<\/span>\u00a0 it could be <span class=\"lang:default decode:true crayon-inline \">SUM(tips)<\/span>\u00a0 or <span class=\"lang:default decode:true crayon-inline \">AVG(fare)<\/span>\u00a0 etc\u2026The where parameters are the individual where clauses to apply &#8211; these are sent as arrays of the form [field, operator, value]<\/span><\/p>\n<pre class=\"lang:go decode:true \">func whereTimePeriod(period string, query url.Values) string {\r\n\twhere := \"\"\r\n\tif period == \"day\" {\r\n\t\tmonth := query[\"month\"][0]\r\n\t\tif month == \"1\" {\r\n\t\t\twhere = `pickupDate &lt;= \"2016-01-31 23:59:59\"`\r\n\t\t} else if month == \"12\" {\r\n\t\t\twhere = `pickupDate &gt;= \"2016-12-01 00:00:00\"`\r\n\t\t} else {\r\n\t\t\tmonthInt, _ := strconv.ParseFloat(month, 64)\r\n\t\t\twhere = fmt.Sprintf(`pickupDate &gt;= \"2016-%02g-01T00:00:00\" AND pickupDate &lt;= \"2016-%02g-31T23:59:59\"`, monthInt, monthInt)\r\n\t\t}\r\n\t} else if period == \"hour\" {\r\n\t\tmonth := query[\"month\"][0]\r\n\t\tmonthInt, _ := strconv.ParseFloat(month, 64)\r\n\t\tday := query[\"day\"][0]\r\n\t\tdayInt, _ := strconv.ParseFloat(day, 64)\r\n\t\twhere = fmt.Sprintf(`pickupDate &gt; \"2016-%02g-%02gT00:00:00\" AND pickupDate &lt;= \"2016-%02g-%02gT23:59:59\"`, monthInt, dayInt, monthInt, dayInt)\r\n\t}\r\n\r\n\treturn where\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">The <span class=\"lang:default decode:true crayon-inline \">whereTimePeriod<\/span>\u00a0<\/span><span style=\"font-weight: 400\">\u00a0<\/span><span style=\"font-weight: 400\">function generates the time bounding part of the where clause by extracting the period from the query string. Depending on the value of the period parameter different logic is applied to build up the where clause, if the entire year is required then an empty where clause is returned.<\/span><\/p>\n<pre class=\"lang:go decode:true \">func processQueryString(queryString url.Values) (*queryOptions, error) {\r\n\taggregate := queryString[\"aggregate\"][0]\r\n\tperiod := \"month\"\r\n\twhere := \"\"\r\n\tnumParams := 0\r\n\tvar params []interface{}\r\n\r\n\tif len(queryString[\"period\"]) &gt; 0 {\r\n\t\tperiod = queryString[\"period\"][0]\r\n\t\twhere = whereTimePeriod(period, queryString)\r\n\t}\r\n\r\n\tfor _, cond := range queryString[\"where\"] {\r\n\t\tnumParams++\r\n\t\tcondParts := strings.Split(cond, \",\")\r\n\t\tif len(where) &gt; 0 {\r\n\t\t\twhere = fmt.Sprintf(\"%s AND %s %s $%d\", where, condParts[0], condParts[1], numParams)\r\n\t\t} else {\r\n\t\t\twhere = fmt.Sprintf(\"%s %s $%d\", condParts[0], condParts[1], numParams)\r\n\t\t}\r\n\t\tval, err := strconv.Atoi(condParts[2])\r\n\t\tif err != nil {\r\n\t\t\treturn nil, err\r\n\t\t}\r\n\t\tparams = append(params, val)\r\n\t}\r\n\r\n\tif len(where) &gt; 0 {\r\n\t\twhere = fmt.Sprintf(\"WHERE %s\", where)\r\n\t}\r\n\r\n\treturn &amp;queryOptions{\r\n\t\tAggregate: aggregate,\r\n\t\tWhere:     where,\r\n\t\tPeriod:    period,\r\n\t\tParams:    params,\r\n\t}, nil\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Once the time bounded part is built then each of the where parameters that the frontend has provided can be added on. You can see that rather than including the where values using string formatting we are using query parameters. This is a best practice to avoid SQL injection.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Once the query has been executed then the <span class=\"lang:default decode:true crayon-inline \">processResults<\/span>\u00a0<\/span><span style=\"font-weight: 400\">\u00a0<\/span><span style=\"font-weight: 400\">function is executed, which looks like:<\/span><\/p>\n<pre class=\"lang:go decode:true \">func processResults(results gocb.AnalyticsResults) (*calendarData, error) {\r\n\tvar row map[string]interface{}\r\n\tvar dateParts []float64\r\n\tvar aggregates []float64\r\n\tfor results.Next(&amp;row) {\r\n\t\tif datePart, ok := row[\"period\"]; ok {\r\n\t\t\tdateParts = append(dateParts, datePart.(float64))\r\n\t\t\taggregates = append(aggregates, row[\"aggregate\"].(float64))\r\n\t\t}\r\n\t}\r\n\tif err := results.Close(); err != nil {\r\n\t\treturn nil, err\r\n\t}\r\n\r\n\treturn &amp;calendarData{\r\n\t\tDateParts: dateParts,\r\n\t\tAggregate: aggregates,\r\n\t}, nil\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">It iterates over the results using <span class=\"lang:default decode:true crayon-inline \">results.Next(&amp;row)<\/span>\u00a0<\/span><span style=\"font-weight: 400\">\u00a0<\/span><span style=\"font-weight: 400\">and for each result pulls out the time period that the result is for as a number, i.e.. the hour (0-23), day (1-31) or month (1-12). It also pulls out the aggregated value that corresponds to that time period. At the end is a call to <\/span><span style=\"font-weight: 400\">r<span class=\"lang:default decode:true crayon-inline \">esults.Close()<\/span>\u00a0<\/span><span style=\"font-weight: 400\">which checks for any errors to ensure that all of the data has been read correctly.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Using the frontend we can easily try out different aggregates for different fields, apply where clauses and drill into the data to get a more granular view on things. For example we probably want to know in which month taxis generated the most money:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5886 size-large\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52-1024x576.png\" alt=\"Chart with execution of sum fares query\" width=\"900\" height=\"506\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52-1024x576.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52-300x169.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52-768x432.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52-1536x864.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52-1320x743.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52.png 2048w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Let\u2019s dig into this by clicking on the dot corresponding to May:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5888 size-large\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/10\/Screen-Shot-2018-10-08-at-12.19.15-1024x568.png\" alt=\"Chart for query of sum fares for the month of May\" width=\"900\" height=\"499\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.19.15-1024x568.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.19.15-300x166.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.19.15-768x426.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.19.15-1536x852.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.19.15-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.19.15-1320x732.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.19.15.png 2048w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<p><span style=\"font-weight: 400\">It looks like the most money is generated on weekends, that makes sense. As it\u2019s nice in May and weekends are most popular maybe most trips are multiple passengers going to see the sights together?<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5887 size-large\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/10\/Screen-Shot-2018-10-08-at-12.24.57-1024x574.png\" alt=\"Chart for the query of count * for the month of May where passengers is greater than 1\" width=\"900\" height=\"504\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.24.57-1024x574.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.24.57-300x168.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.24.57-768x431.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.24.57-1536x861.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.24.57-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.24.57-1320x740.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.24.57.png 2048w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Doesn\u2019t look like it! There are lots of other comparisons that we could make, like fares vs tips or the number of journeys vs number of journeys with no tips. This dataset also has location data so we could do things like create heatmaps of pickup locations.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Conclusion<\/span><\/h2>\n<p><span style=\"font-weight: 400\">In this example, we walked through how a simple query, which might even be ad-hoc, can be used to quickly analyze a dataset with a variety of metrics, all without requiring the creation of indexes. Couchbase Analytics will add this great capability to the Couchbase platform when made generally available. Golang developers have access now through the 6.0 beta.<\/span><\/p>\n<p><span style=\"font-weight: 400\">We\u2019d love your feedback! \u00a0Please <a href=\"https:\/\/www.couchbase.com\/download\/\">download<\/a><\/span><span style=\"font-weight: 400\">\u00a0Couchbase Server 6.0 beta today and try the updated <a href=\"https:\/\/docs.couchbase.com\/server\/6.0\/analytics\/introduction.html\">Couchbase Analytics<\/a>. \u00a0We\u2019ll be watching for your comments at <a href=\"https:\/\/www.couchbase.com\/forums\/\">www.couchbase.com\/forums\/<\/a> on anything from analytics to the Go SDK.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post illustrates the use of Couchbase Analytics with the Couchbase Go SDK. Couchbase Analytics is a new service available in Couchbase Server 6.0, you can read more at https:\/\/docs.couchbase.com\/server\/6.0\/analytics\/introduction.html. In this post we\u2019re going to use a real world [&hellip;]<\/p>\n","protected":false},"author":17480,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[2294,1820,1812,2201],"tags":[],"ppma_author":[8944],"class_list":["post-5885","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","category-golang","category-n1ql-query","category-tools-sdks"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>A Couchbase Analytics Example using the Go SDK<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Couchbase Analytics Example using the Go SDK\" \/>\n<meta property=\"og:description\" content=\"This post illustrates the use of Couchbase Analytics with the Couchbase Go SDK. Couchbase Analytics is a new service available in Couchbase Server 6.0, you can read more at https:\/\/docs.couchbase.com\/server\/6.0\/analytics\/introduction.html. In this post we\u2019re going to use a real world [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-10-11T19:04:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T04:20:30+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2048\" \/>\n\t<meta property=\"og:image:height\" content=\"1152\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Charles Dixon, Software Engineer, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Charles Dixon, Software Engineer, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/\"},\"author\":{\"name\":\"Charles Dixon, Senior Software Engineer, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/cd440eed5f00a0f702828c9f3697f6c3\"},\"headline\":\"A Couchbase Analytics Example using the Go SDK\",\"datePublished\":\"2018-10-11T19:04:19+00:00\",\"dateModified\":\"2025-06-14T04:20:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/\"},\"wordCount\":1520,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Couchbase Analytics\",\"GoLang\",\"SQL++ \\\/ N1QL Query\",\"Tools &amp; SDKs\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/\",\"name\":\"A Couchbase Analytics Example using the Go SDK\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2018-10-11T19:04:19+00:00\",\"dateModified\":\"2025-06-14T04:20:30+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/a-couchbase-analytics-example-using-the-go-sdk\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Couchbase Analytics Example using the Go SDK\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/cd440eed5f00a0f702828c9f3697f6c3\",\"name\":\"Charles Dixon, Senior Software Engineer, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6359fe0ffc778647ed89c818c1474ac1151dae1fe4bf7315ad38a0ec92cfe9af?s=96&d=mm&r=g9cb6d8cbb9125a775db01b9a74258c36\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6359fe0ffc778647ed89c818c1474ac1151dae1fe4bf7315ad38a0ec92cfe9af?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6359fe0ffc778647ed89c818c1474ac1151dae1fe4bf7315ad38a0ec92cfe9af?s=96&d=mm&r=g\",\"caption\":\"Charles Dixon, Senior Software Engineer, Couchbase\"},\"description\":\"Charles Dixon is a Senior Software Engineer at Couchbase. He primarily works on the Couchbase Go SDK.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/author\\\/charles-dixon\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"A Couchbase Analytics Example using the Go SDK","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/","og_locale":"en_US","og_type":"article","og_title":"A Couchbase Analytics Example using the Go SDK","og_description":"This post illustrates the use of Couchbase Analytics with the Couchbase Go SDK. Couchbase Analytics is a new service available in Couchbase Server 6.0, you can read more at https:\/\/docs.couchbase.com\/server\/6.0\/analytics\/introduction.html. In this post we\u2019re going to use a real world [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/","og_site_name":"The Couchbase Blog","article_published_time":"2018-10-11T19:04:19+00:00","article_modified_time":"2025-06-14T04:20:30+00:00","og_image":[{"width":2048,"height":1152,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/Screen-Shot-2018-10-08-at-12.17.52.png","type":"image\/png"}],"author":"Charles Dixon, Software Engineer, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Charles Dixon, Software Engineer, Couchbase","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/"},"author":{"name":"Charles Dixon, Senior Software Engineer, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/cd440eed5f00a0f702828c9f3697f6c3"},"headline":"A Couchbase Analytics Example using the Go SDK","datePublished":"2018-10-11T19:04:19+00:00","dateModified":"2025-06-14T04:20:30+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/"},"wordCount":1520,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","articleSection":["Couchbase Analytics","GoLang","SQL++ \/ N1QL Query","Tools &amp; SDKs"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/","url":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/","name":"A Couchbase Analytics Example using the Go SDK","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2018-10-11T19:04:19+00:00","dateModified":"2025-06-14T04:20:30+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/a-couchbase-analytics-example-using-the-go-sdk\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"A Couchbase Analytics Example using the Go SDK"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/cd440eed5f00a0f702828c9f3697f6c3","name":"Charles Dixon, Senior Software Engineer, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/6359fe0ffc778647ed89c818c1474ac1151dae1fe4bf7315ad38a0ec92cfe9af?s=96&d=mm&r=g9cb6d8cbb9125a775db01b9a74258c36","url":"https:\/\/secure.gravatar.com\/avatar\/6359fe0ffc778647ed89c818c1474ac1151dae1fe4bf7315ad38a0ec92cfe9af?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6359fe0ffc778647ed89c818c1474ac1151dae1fe4bf7315ad38a0ec92cfe9af?s=96&d=mm&r=g","caption":"Charles Dixon, Senior Software Engineer, Couchbase"},"description":"Charles Dixon is a Senior Software Engineer at Couchbase. He primarily works on the Couchbase Go SDK.","url":"https:\/\/www.couchbase.com\/blog\/author\/charles-dixon\/"}]}},"acf":[],"authors":[{"term_id":8944,"user_id":17480,"is_guest":0,"slug":"charles-dixon","display_name":"Charles Dixon, Software Engineer, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/6359fe0ffc778647ed89c818c1474ac1151dae1fe4bf7315ad38a0ec92cfe9af?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/5885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/17480"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=5885"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/5885\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=5885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=5885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=5885"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=5885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}