{"id":4475,"date":"2025-01-20T11:24:26","date_gmt":"2025-01-20T19:24:26","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/"},"modified":"2025-01-20T11:24:26","modified_gmt":"2025-01-20T19:24:26","slug":"couchbase-shell-time-series-data","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/couchbase-shell-time-series-data\/","title":{"rendered":"Graph Time Series Data From the Comfort of Your Terminal"},"content":{"rendered":"\n<p><span>If you have been following the earlier posts on the Couchbase blog, you have seen <a href=\"https:\/\/www.couchbase.com\/blog\/tag\/cbshell\/\">content about Couchbase Shell<\/a> latest release. I am trying different things and today I wanted to see what I could do with time series datasets.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span>Ingest time series data<\/span><\/h2>\n\n\n\n<p><span>Browsing Kaggle, I found <a href=\"https:\/\/www.kaggle.com\/datasets\/berkeleyearth\/climate-change-earth-surface-temperature-data?resource=download\">temperature data per City<\/a><\/span><span>. I have downloaded it. It&#8217;s about 500Mb and that makes it hard to manipulate as a whole. But, of course, it&#8217;s a text file so we can easily peek at the data structure like so:<\/span><\/p>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; wrap-toggle=&#8221;false&#8221; lang=&#8221;sh&#8221; decode=&#8221;true&#8221;]&gt; open GlobalLandTemperaturesByCity.csv | first 10<\/p>\n<p>\u256d\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e<br \/>\n\u2502 # \u2502 \u00a0 \u00a0 dt \u00a0 \u00a0 \u2502 AverageTemperature \u2502 AverageTemperatureUncertainty \u2502 City\u00a0 \u2502 Country \u2502 Latitude \u2502 Longitude \u2502<br \/>\n\u251c\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 0 \u2502 1743-11-01 \u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 6.07 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 1.74 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 1 \u2502 1743-12-01 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 2 \u2502 1744-01-01 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 3 \u2502 1744-02-01 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 4 \u2502 1744-03-01 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 5 \u2502 1744-04-01 \u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 5.79 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 3.62 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 6 \u2502 1744-05-01 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 10.64 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 1.28 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 7 \u2502 1744-06-01 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 14.05 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 1.35 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 8 \u2502 1744-07-01 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 16.08 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 1.40 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2502 9 \u2502 1744-08-01 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 \u00c5rhus \u2502 Denmark \u2502 57.05N \u00a0 \u2502 10.33E\u00a0 \u00a0 \u2502<br \/>\n\u2570\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f[\/crayon]<\/p>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; open GlobalLandTemperaturesByCity.csv | length<\/p>\n<p>8599212[\/crayon]<\/p>\n\n\n\n<p><span>8599212 lines, this is going to be 8599211 documents. My end goal is to see a temperature graph of several cities over the years. To do that, I am going to import everything to an import bucket first, then I will transform the data into time series. <\/span><\/p>\n\n\n\n<p><span>If I import this na\u00efvely, it gives me one doc per city\/month group. So the key of my doc will be like <em>\u00c5rhus:1743-11-01<\/em>. Say I only want to upload the first line, it should look like this:<\/span><\/p>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; open GlobalLandTemperaturesByCity.csv | first 1 | wrap content | insert id { |x| $&#8221;($x.content.City):($x.content.dt)&#8221; }<\/p>\n<p>\u256d\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e<br \/>\n\u2502 # \u2502\u00a0 \u00a0 \u00a0 content\u00a0 \u00a0 \u00a0 \u2502\u00a0 \u00a0 \u00a0 \u00a0 id\u00a0 \u00a0 \u00a0 \u00a0 \u2502<br \/>\n\u251c\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 0 \u2502 {record 7 fields} \u2502 \u00c5rhus:1743-11-01 \u2502<br \/>\n\u2570\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f<\/p>\n<p>&gt; open GlobalLandTemperaturesByCity.csv | first 1 | wrap content | insert id { |x| $&#8221;($x.content.City):($x.content.dt)&#8221; } |doc upsert<\/p>\n<p>\u256d\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e<br \/>\n\u2502 # \u2502 processed \u2502 success \u2502 failed \u2502 failures \u2502 cluster \u2502<br \/>\n\u251c\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502 0 \u2502 \u00a0 \u00a0 \u00a0 \u00a0 1 \u2502 \u00a0 \u00a0 \u00a0 1 \u2502\u00a0 \u00a0 \u00a0 0 \u2502\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2502 capella \u2502<br \/>\n\u2570\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f<br \/>\n[\/crayon]<\/p>\n\n\n\n<p><span>And now that I know it works, let&#8217;s get everything, and batch it:<\/span><\/p>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums-toggle=&#8221;false&#8221; wrap=&#8221;true&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]open GlobalLandTemperaturesByCity.csv | par-each -t 5 {|x| wrap content | insert id {$&#8221;($x.City):($x.dt)&#8221; } } | doc upsert<\/p>\n<p>[\/crayon]<\/p>\n\n\n\n<p><span>I have created a <\/span><span>series<\/span><span> collection in which I import the result of a <em>SELECT<\/em> aggregation, getting all the dates as timestamps and all the <\/span><i><span>AverageTemperature <\/span><\/i><span>as value:<\/span><\/p>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]query &#8216;<\/p>\n<p>INSERT INTO series(KEY _k, VALUE _v)<br \/>\n\u00a0\u00a0\u00a0\u00a0SELECT a.City _k,<br \/>\n\u00a0\u00a0\u00a0\u00a0{&#8220;City&#8221;: a.City ,<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;ts_start&#8221; : MIN(STR_TO_MILLIS(a.dt)),<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;ts_end&#8221; : MAX(STR_TO_MILLIS(a.dt)),<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;ts_data&#8221; : ARRAY_AGG([STR_TO_MILLIS(a.dt), a.AverageTemperature]) } _v<br \/>\n\u00a0\u00a0\u00a0\u00a0FROM import a<br \/>\n\u00a0\u00a0\u00a0\u00a0WHERE a.dt BETWEEN &#8220;1700-01-01&#8221; AND &#8220;2020-12-31&#8221;<br \/>\n\u00a0\u00a0\u00a0\u00a0GROUP BY a.City;<br \/>\n\u00a0\u00a0\u00a0\u00a0&#8216;<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0INSERT INTO series(KEY _k, VALUE _v)<br \/>\n\u00a0\u00a0\u00a0\u00a0SELECT a.City _k,<br \/>\n\u00a0\u00a0\u00a0\u00a0{&#8220;City&#8221;: a.City ,<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;ts_start&#8221; : MIN(STR_TO_MILLIS(a.dt)),<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;ts_end&#8221; : MAX(STR_TO_MILLIS(a.dt)),<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;ts_data&#8221; : ARRAY_AGG([STR_TO_MILLIS(a.dt), a.AverageTemperature]) } _v<br \/>\n\u00a0\u00a0\u00a0\u00a0FROM import a<br \/>\n\u00a0\u00a0\u00a0\u00a0WHERE SUBSTR(a.City,0,1) = &#8220;Z&#8221; AND a.dt BETWEEN &#8220;2010-01-01&#8221; AND &#8220;2020-12-31&#8221;\u00a0<br \/>\n\u00a0\u00a0\u00a0\u00a0GROUP BY a.City;<br \/>\n[\/crayon]<\/p>\n\n\n\n<p><span>And now all the data is available as time series. Say I want the data from Paris, I can use the <em>_timeseries<\/em> function like this:<\/span><\/p>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; let ts_ranges = [946684800000,1375315200000]; query $&#8221;SELECT t._t time, t._v0 `value` FROM series AS d UNNEST _timeseries(d, {&#8220;ts_ranges&#8221;:($ts_ranges)}) AS t WHERE d.city = &#8220;Paris&#8221; AND (d.ts_start &lt;= ($ts_ranges.1) AND d.ts_end &gt;= ($ts_ranges.0) );&#8221; | reject cluster | to csv\u00a0\u00a0<\/p>\n<p>time,value<br \/>\n946684800000,3.845<br \/>\n949363200000,6.587000000000001<br \/>\n951868800000,7.872000000000001<br \/>\n954547200000,10.067<br \/>\n957139200000,15.451<br \/>\n959817600000,17.666<br \/>\n962409600000,16.954<br \/>\n965088000000,19.512<br \/>\n967766400000,16.548000000000002<br \/>\n970358400000,11.675999999999998<br \/>\n&#8230;.[\/crayon]<\/p>\n\n\n\n<p><span>To speed things up you can create the following index: <\/span><span><code>CREATE INDEX ix1 ON series(City, ts_end, ts_start);<\/code><\/span><\/p>\n\n\n\n<p><span>Notice the use of the <em>ts_ranges<\/em> variable at the beginning. You can easily reuse those values in a template <em>String<\/em>. They start with a<em> $<\/em> sign and variables must be in parenthesis like <em>($my_variable)<\/em>. Which also means that now you need to escape parenthesis character as well as double quotes.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span>Plot time series<\/span><\/h2>\n\n\n\n<p><span>There are a variety of terminal plotting libraries, here I am using <\/span><a href=\"https:\/\/github.com\/red-data-tools\/YouPlot\"><span>youplot<\/span><\/a>:<\/p>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; wrap=&#8221;true&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; let ts_ranges = [946684800000,1375315200000]; query $&#8221;SELECT t._t date, t._v0 `value` FROM series AS d UNNEST _timeseries(d, {&#8220;ts_ranges&#8221;:($ts_ranges)}) AS t WHERE d.city = &#8220;Paris&#8221; AND (d.ts_start &lt;= ($ts_ranges.1) AND d.ts_end &gt;= ($ts_ranges.0) );&#8221; | reject cluster | to csv\u00a0 | uplot line -d, &#8211;xlim 946684800000,1375315200000 &#8211;ylim -20,35 &#8211;title &#8220;global temperature in Paris&#8221; &#8211;xlabel date &#8211;ylabel temperature`[\/crayon]<\/p>\n\n\n\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image1-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-16784 size-large\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image1-1-1024x677-1.png\" alt=\"\" width=\"900\" height=\"595\"><\/a><\/p>\n\n\n\n<p><span>Now that is all great but ideally I want to have several cities in there to compare them. Any additional CSV columns are picked up automatically as long as you run <\/span><span>youplot lines<\/span><span>. Doing things gradually, let&#8217;s start with the support of multiple cities in the query. So a couple changes here:<\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span>grouping the data by time<\/span><\/li>\n\n\n<li><span>adding <\/span><em><span>d.city IN ($city)<\/span><\/em><span> to the where clause. This works because the city array is a String literal of a JSON array. Let&#8217;s take a look at the answer as a JSON doc:<\/span><\/li>\n\n<\/ul>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; let ts_ranges = [946684800000,1375315200000]; let city = [&#8216;&#8221;Aba&#8221;&#8216;,'&#8221;Berlin&#8221;&#8216;,'&#8221;London&#8221;&#8216;,'&#8221;Paris&#8221;&#8216;]; query $&#8221;SELECT t._t date, (\u00a0 ARRAY_AGG({&#8220;city&#8221;: d.city, &#8220;temp&#8221;:t._v0}) )\u00a0 FROM series AS d UNNEST _timeseries(d, {&#8220;ts_ranges&#8221;:($ts_ranges)}) AS t WHERE d.city IN ($city) AND (d.ts_start &lt;= ($ts_ranges.1) AND d.ts_end &gt;= ($ts_ranges.0) ) GROUP BY t._t ORDER BY t._t;&#8221; | reject cluster | first |to json<\/p>\n<p>[<br \/>\n\u00a0\u00a0{<br \/>\n\u00a0\u00a0\u00a0\u00a0&#8220;date&#8221;: &#8220;2000-01-01&#8221;,<br \/>\n\u00a0\u00a0\u00a0\u00a0&#8220;$1&#8221;:<br \/>\n\u00a0\u00a0\u00a0\u00a0[<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;city&#8221;: &#8220;Aba&#8221;,<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;temp&#8221;: 26.985000000000007<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;city&#8221;: &#8220;Berlin&#8221;,<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;temp&#8221;: 1.3239999999999998<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;city&#8221;: &#8220;London&#8221;,<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;temp&#8221;: 4.6930000000000005<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;city&#8221;: &#8220;Paris&#8221;,<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;temp&#8221;: 3.845<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<br \/>\n\u00a0\u00a0\u00a0\u00a0]<br \/>\n\u00a0\u00a0}<br \/>\n][\/crayon]<\/p>\n\n\n\n<p><span>But this cannot turn into a CSV, even if you flatten everything like this:<\/span><\/p>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; wrap=&#8221;true&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; let ts_ranges = [946684800000,1375315200000]; let city = [&#8216;&#8221;Aba&#8221;&#8216;,'&#8221;Berlin&#8221;&#8216;,'&#8221;London&#8221;&#8216;,'&#8221;Paris&#8221;&#8216;]; query $&#8221;SELECT t._t date, (\u00a0 ARRAY_AGG({&#8220;city&#8221;: d.city, &#8220;temp&#8221;:t._v0}) )\u00a0 FROM series AS d UNNEST _timeseries(d, {&#8220;ts_ranges&#8221;:($ts_ranges)}) AS t WHERE d.city IN ($city) AND (d.ts_start &lt;= ($ts_ranges.1) AND d.ts_end &gt;= ($ts_ranges.0) ) GROUP BY t._t ORDER BY t._t;&#8221; |reject cluster | first |flatten|flatten|to csv<\/p>\n<p>date,city,temp<br \/>\n2000-01-01,Aba,26.985000000000007<br \/>\n2000-01-01,Berlin,1.3239999999999998<br \/>\n2000-01-01,London,4.6930000000000005<br \/>\n2000-01-01,Paris,3.845[\/crayon]<\/p>\n\n\n\n<p><span>So we can transform it into an object like so: <\/span><span><code>Object v.city : v.temp FOR v IN ARRAY_AGG({\"city\": d.city, \"temp\":t._v0}) when v IS NOT MISSING END<\/code><\/span><\/p>\n\n\n<p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; wrap=&#8221;true&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; let ts_ranges = [946684800000,1375315200000]; let city = [&#8216;&#8221;Aba&#8221;&#8216;,'&#8221;Berlin&#8221;&#8216;,'&#8221;London&#8221;&#8216;,'&#8221;Paris&#8221;&#8216;]; query $&#8221;SELECT t._t date, ( Object v.city : v.temp FOR v IN ARRAY_AGG({&#8220;city&#8221;: d.city, &#8220;temp&#8221;:t._v0}) when v IS NOT MISSING END)\u00a0 FROM series AS d UNNEST _timeseries(d, {&#8220;ts_ranges&#8221;:($ts_ranges)}) AS t WHERE d.city IN ($city) AND (d.ts_start &lt;= ($ts_ranges.1) AND d.ts_end &gt;= ($ts_ranges.0) ) GROUP BY t._t ORDER BY t._t;&#8221; |reject cluster | first | to json<\/p>\n<p>{<br \/>\n\u00a0\u00a0&#8220;date&#8221;: &#8220;2000-01-01&#8221;,<br \/>\n\u00a0\u00a0&#8220;$1&#8221;:<br \/>\n\u00a0\u00a0{<br \/>\n\u00a0\u00a0\u00a0\u00a0&#8220;Aba&#8221;: 26.985000000000007,<br \/>\n\u00a0\u00a0\u00a0\u00a0&#8220;Berlin&#8221;: 1.3239999999999998,<br \/>\n\u00a0\u00a0\u00a0\u00a0&#8220;London&#8221;: 4.6930000000000005,<br \/>\n\u00a0\u00a0\u00a0\u00a0&#8220;Paris&#8221;: 3.845<br \/>\n\u00a0\u00a0}<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p><span>Which can now be flatten into a CSV:<\/span><\/p>\n\n\n\n<p><p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; open GlobalLandTemperaturesByCity.csv | length<\/p>\n<p>8599212[\/crayon]<\/p>\n0<\/p>\n\n\n\n<p><span>And with that we are ready to plot several lines:<\/span><\/p>\n\n\n\n<p><p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; open GlobalLandTemperaturesByCity.csv | length<\/p>\n<p>8599212[\/crayon]<\/p>\n1<\/p>\n\n\n\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image2-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-16785 size-large\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image2-1-1024x676-1.png\" alt=\"\" width=\"900\" height=\"594\"><\/a><\/p>\n\n\n\n<p><span>To make that easier, you can use functions. Create a <em>.nu<\/em> file, like <em>temp.nu<\/em>, with the following content:<\/span><\/p>\n\n\n\n<p><p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; open GlobalLandTemperaturesByCity.csv | length<\/p>\n<p>8599212[\/crayon]<\/p>\n2<\/p>\n\n\n\n<p><span>Then if you source it it becomes much easier to use:<\/span><\/p>\n\n\n\n<p><p>[crayon line-height=&#8221;12&#8243; nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&gt; open GlobalLandTemperaturesByCity.csv | length<\/p>\n<p>8599212[\/crayon]<\/p>\n3<\/p>\n\n\n\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image3-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16786\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image3-1-1024x683-1.png\" alt=\"\" width=\"900\" height=\"600\"><\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><span>I hope this gave you a quick overview of Couchbase time series support, of Couchbase Shell data manipulation, and how you can use other shell commands like <em>youplot<\/em> to make things more integrated and interesting. You could easily generate a full report in various formats from a <a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a> for instance, endless possibilities!<\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Read more posts about <a href=\"https:\/\/www.couchbase.com\/blog\/tag\/cbshell\/\">Couchbase Shell<\/a>.<\/li>\n\n<\/ul>\n\n\n\n<p>\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you have been following the earlier posts on the Couchbase blog, you have seen content about Couchbase Shell latest release. I am trying different things and today I wanted to see what I could do with time series datasets. Ingest time series data Browsing Kaggle, I found temperature data per City. I have downloaded [&hellip;]<\/p>\n","protected":false},"author":49,"featured_media":4474,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[136,18],"tags":[889,890,665],"ppma_author":[110],"class_list":["post-4475","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-n1ql-query","tag-cbshell","tag-couchbase-shell","tag-time-series"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.6 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Graph Time Series Data From the Comfort of Your Terminal - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Learn to manage and analyze time series data with Couchbase Shell, from ingestion to visualization using global temperature datasets.\" \/>\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\/pt\/couchbase-shell-time-series-data\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Graph Time Series Data From the Comfort of Your Terminal\" \/>\n<meta property=\"og:description\" content=\"Learn to manage and analyze time series data with Couchbase Shell, from ingestion to visualization using global temperature datasets.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/couchbase-shell-time-series-data\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-20T19:24:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/blog-couchbase-shell-time-series-graph.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2400\" \/>\n\t<meta property=\"og:image:height\" content=\"1256\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Laurent Doguin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ldoguin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laurent Doguin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/\"},\"author\":{\"name\":\"Laurent Doguin\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\"},\"headline\":\"Graph Time Series Data From the Comfort of Your Terminal\",\"datePublished\":\"2025-01-20T19:24:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/\"},\"wordCount\":1338,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/blog-couchbase-shell-time-series-graph.png\",\"keywords\":[\"cbshell\",\"couchbase shell\",\"time series\"],\"articleSection\":[\"Best Practices and Tutorials\",\"SQL++ \\\/ N1QL Query\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/\",\"name\":\"Graph Time Series Data From the Comfort of Your Terminal - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/blog-couchbase-shell-time-series-graph.png\",\"datePublished\":\"2025-01-20T19:24:26+00:00\",\"description\":\"Learn to manage and analyze time series data with Couchbase Shell, from ingestion to visualization using global temperature datasets.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/blog-couchbase-shell-time-series-graph.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/blog-couchbase-shell-time-series-graph.png\",\"width\":2400,\"height\":1256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/couchbase-shell-time-series-data\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Graph Time Series Data From the Comfort of Your Terminal\"}]},{\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"width\":\"1024\",\"height\":\"1024\",\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\",\"name\":\"Laurent Doguin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g12929ce99397769f362b7a90d6b85071\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"caption\":\"Laurent Doguin\"},\"description\":\"Laurent is a nerdy metal head who lives in Paris. He mostly writes code in Java and structured text in AsciiDoc, and often talks about data, reactive programming and other buzzwordy stuff. He is also a former Developer Advocate for Clever Cloud and Nuxeo where he devoted his time and expertise to helping those communities grow bigger and stronger. He now runs Developer Relations at Couchbase.\",\"sameAs\":[\"https:\\\/\\\/x.com\\\/ldoguin\"],\"honorificPrefix\":\"Mr\",\"birthDate\":\"1985-06-07\",\"gender\":\"male\",\"award\":[\"Devoxx Champion\",\"Couchbase Legend\"],\"knowsAbout\":[\"Java\"],\"knowsLanguage\":[\"English\",\"French\"],\"jobTitle\":\"Director Developer Relation & Strategy\",\"worksFor\":\"Couchbase\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/pt\\\/author\\\/laurent-doguin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Graph Time Series Data From the Comfort of Your Terminal - The Couchbase Blog","description":"Learn to manage and analyze time series data with Couchbase Shell, from ingestion to visualization using global temperature datasets.","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\/pt\/couchbase-shell-time-series-data\/","og_locale":"pt_BR","og_type":"article","og_title":"Graph Time Series Data From the Comfort of Your Terminal","og_description":"Learn to manage and analyze time series data with Couchbase Shell, from ingestion to visualization using global temperature datasets.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/couchbase-shell-time-series-data\/","og_site_name":"The Couchbase Blog","article_published_time":"2025-01-20T19:24:26+00:00","og_image":[{"width":2400,"height":1256,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/blog-couchbase-shell-time-series-graph.png","type":"image\/png"}],"author":"Laurent Doguin","twitter_card":"summary_large_image","twitter_creator":"@ldoguin","twitter_misc":{"Written by":"Laurent Doguin","Est. reading time":"4 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/"},"author":{"name":"Laurent Doguin","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e"},"headline":"Graph Time Series Data From the Comfort of Your Terminal","datePublished":"2025-01-20T19:24:26+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/"},"wordCount":1338,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/blog-couchbase-shell-time-series-graph.png","keywords":["cbshell","couchbase shell","time series"],"articleSection":["Best Practices and Tutorials","SQL++ \/ N1QL Query"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/","url":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/","name":"Graph Time Series Data From the Comfort of Your Terminal - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/blog-couchbase-shell-time-series-graph.png","datePublished":"2025-01-20T19:24:26+00:00","description":"Learn to manage and analyze time series data with Couchbase Shell, from ingestion to visualization using global temperature datasets.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/blog-couchbase-shell-time-series-graph.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/blog-couchbase-shell-time-series-graph.png","width":2400,"height":1256},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-shell-time-series-data\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Graph Time Series Data From the Comfort of Your Terminal"}]},{"@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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","width":"1024","height":"1024","caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e","name":"Laurent Doguin","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g12929ce99397769f362b7a90d6b85071","url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","caption":"Laurent Doguin"},"description":"Laurent is a nerdy metal head who lives in Paris. He mostly writes code in Java and structured text in AsciiDoc, and often talks about data, reactive programming and other buzzwordy stuff. He is also a former Developer Advocate for Clever Cloud and Nuxeo where he devoted his time and expertise to helping those communities grow bigger and stronger. He now runs Developer Relations at Couchbase.","sameAs":["https:\/\/x.com\/ldoguin"],"honorificPrefix":"Mr","birthDate":"1985-06-07","gender":"male","award":["Devoxx Champion","Couchbase Legend"],"knowsAbout":["Java"],"knowsLanguage":["English","French"],"jobTitle":"Director Developer Relation & Strategy","worksFor":"Couchbase","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/laurent-doguin\/"}]}},"acf":[],"authors":[{"term_id":110,"user_id":49,"is_guest":0,"slug":"laurent-doguin","display_name":"Laurent Doguin","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4475","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/49"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=4475"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4475\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/4474"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=4475"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=4475"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=4475"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=4475"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}