{"id":14594,"date":"2023-07-26T12:16:39","date_gmt":"2023-07-26T19:16:39","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=14594"},"modified":"2024-02-07T11:56:01","modified_gmt":"2024-02-07T19:56:01","slug":"introducing-couchbase-time-series","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/","title":{"rendered":"Introducing Couchbase Time Series"},"content":{"rendered":"<p><span style=\"font-weight: 400\">Couchbase is excited to announce the release of a new time-series feature as part of Couchbase 7.2. This feature is built on top of the robust Couchbase distributed database architecture, which is designed to scale horizontally as your data grows, all while providing built-in redundancy and\u00a0 high availability. This means that as your business grows and your time series data needs increase, Couchbase can effortlessly expand to meet those needs, making it an ideal solution for businesses of all sizes.<\/span><\/p>\n<p><span style=\"font-weight: 400\">This innovative new technique to manage time series data opens up a whole new world of possibilities for Couchbase users. With the ability to store and analyze vast amounts of time series data using Couchbase SQL++ and SDKs. This allows users to leverage their existing knowledge and infrastructure, making it easy to set up and unlock powerful insights to explore data trends with ease.\u00a0<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Key benefits of time series\u00a0<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Time series data are stored in JSON documents in the Couchbase Multi Model database. It provides the same high performance, advanced caching for fast data retrieval and low latency. Couchbase Query SQL++ and Index service enhance the data retrieval capabilities to allow complex analytical query use cases.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Time Series data support in Couchbase provides these additional benefits:<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none\">\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Efficient storage for large volume of time series data points<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Optimized data structure storage for time stamped data points<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">New advanced time series query capabilities<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Low index storage requirement<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2><span style=\"font-weight: 400\">Examples of time series use cases<\/span><\/h2>\n<p><span style=\"font-weight: 400\"><strong>Financial Trading &#8211; <\/strong>Financial trading relies on the analysis of large amounts of real-time data, including stock prices, currency rates, and commodity prices. Time-series data analysis can help traders identify trends and make informed decisions about buying and selling.<\/span><\/p>\n<p><span style=\"font-weight: 400\"><strong>Internet of Things (IoT) Monitoring &#8211; <\/strong>IoT devices generate a large amount of time-series data, including temperature readings, energy consumption, and sensor data. This data can be analyzed in real-time to detect anomalies and predict equipment failures before they occur.<\/span><\/p>\n<p><span style=\"font-weight: 400\"><strong>Predictive Maintenance &#8211; <\/strong>Many industries rely on expensive equipment and machinery, and downtime can be costly. By analyzing time-series data from sensors and other sources, organizations can predict when equipment is likely to fail, and proactively schedule maintenance to minimize downtime and maximize efficiency.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Key features of Couchbase Time Series<\/span><\/h2>\n<p><span style=\"font-weight: 400\">You can store time series data in Couchbase, using our SDK\/SQL++ to load, and the advanced Analytical query capability with Global Secondary Index to query\/analyze the data in the same way as with normal JSON documents.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Storage efficiency<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Time series datasets are typically very large, with each data point consisting of attributes, such as timestamp, value(s), granularity and other related information. Efficient storage is critical as it can determine how fast the data can be queried for analysis.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Couchbase time series uses two specifications to improve storage efficiency.<\/span><\/p>\n<p><b>The use of arrays for data points<\/b><span style=\"font-weight: 400\"> &#8211; By its very nature, time series data are a series of data points. These data points share a common structure, e.g., time and values, or any other attributes that are associated with the time when the data point was collected.\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Using an array to store a set of the data points for a given range can greatly reduce the storage cost, compared to having to store each individual data point as a separate document in the database.\u00a0<\/span><\/p>\n<p><b>The use of array position<\/b><span style=\"font-weight: 400\"> &#8211; Also note that data point array elements do not have an associated field name, but instead it relies on the position of the element in the array. In this example, the three elements in the array are: the observation date, the opening value, and the closing value of the stock.<\/span><\/p>\n<pre class=\"lang:js decode:true \">docid:\u00a0 \"stock:XYZ:d1\"\r\n{\r\n\u00a0 \"ts_data\": [ [1672531200000, 92.08, 95.62],[1672531201000, 95.62, 99.25],..]\r\n}<\/pre>\n<p><b>Use EPOCH time &#8211;\u00a0<\/b><span style=\"font-weight: 400\"><a href=\"https:\/\/en.wikipedia.org\/wiki\/Epoch_(computing)\">Epoch time<\/a> is used instead of ISO date string in order to reduce the size of each data point, and improve processing time.\u00a0<\/span><\/p>\n<pre class=\"lang:js decode:true \">docid:\u00a0 \"stock:XYZ:d1\"\r\n{\r\n\u00a0 \"ts_data\": [ [1672531200000, 92.08, 95.62],[1672531201000, 95.62, 99.25],..]\r\n\u00a0 \"ts_start\": 1672531200000 \/* dstart and dend denote the *\/\r\n\u00a0 \"ts_end\": \u00a0 1672617599999,\/* time range of all data points in ts_data *\/\u00a0 \u00a0 \u00a0\r\n\u00a0 \"ticker\": \u00a0 \"XYZ\"\r\n}<\/pre>\n<h3><span style=\"font-weight: 400\">Optimized query with a new _timeseries function<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Couchbase Time Series feature includes a new<\/span> <b>_timeseries<\/b> <span style=\"font-weight: 400\">function. The function serves several purposes:<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none\">\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">It dynamically generates the time series objects from the <\/span><span style=\"font-weight: 400\">ts_data <\/span><span style=\"font-weight: 400\">array of arrays<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">It efficiently streams the results when it is used with UNNEST, optimizes response time and memory usage<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">It can automatically generate the timestamp for each data point when the ts_interval parameter is used<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">It supports more advanced time series use cases for irregular time series data points interval, such as instead of a multiple sets of data points per timestamp<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Please refer to the <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/time-series.html\"><span style=\"font-weight: 400\">Couchbase time series documentation<\/span><\/a><span style=\"font-weight: 400\"> for more detail.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Optimized index storage<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Due to the way Couchbase stores time series data, with each data point stored as an element in an array within a JSON document, we can optimize our database indexing strategy. Specifically, since each document contains both the start and end time of all the data points in the array, we can create a single index definition for each document. This means that even for large time series data sets with millions of data points, we can store the data in just a few documents rather than one document per data point.<\/span><\/p>\n<p><span style=\"font-weight: 400\">For example, a time series data set with 1 million data points can be stored in just 1,000 documents, assuming that each <em>ts_data<\/em> array can store up to 1,000 data elements and the document size remains below the 20MB Couchbase JSON document limit. This not only reduces the number of documents needed to store the data, but it also leads to smaller index sizes, improving database performance and reducing disk space requirements.<\/span><\/p>\n<p><span style=\"font-weight: 400\">In short, by taking advantage of Couchbase&#8217;s ability to store time series data as arrays within JSON documents, we can optimize our indexing strategy to significantly reduce the number of documents needed and reduce the index size, resulting in faster query performance and more efficient use of storage resources.<\/span><\/p>\n<pre class=\"lang:js decode:true\">CREATE INDEX ix1 ON docs(ticker, ts_end, ts_start);<\/pre>\n<h3><span style=\"font-weight: 400\">Data Retention\u00a0<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Time Series documents are stored as standard JSON documents in Couchbase. So the same Time-To-Live (TTL) can be set during the data load process.<\/span><\/p>\n<pre class=\"lang:js decode:true \">\/* The document will be automatically removed in 30 days *\/\r\n\r\nINSERT INTO coll1 (KEY, VALUE)\u00a0\r\n\r\n\u00a0\u00a0\u00a0VALUES (\"stock:XYZ:d1\", {\"ticker\":\"XYZ\",..}, {\"expiration\":60*60*24*30});<\/pre>\n<h2><span style=\"font-weight: 400\">Example walkthrough<\/span><\/h2>\n<p><span style=\"font-weight: 400\">So let&#8217;s walk through the process of loading an actual stock price data set into Couchbase using the time series data model as defined by the feature.<\/span><\/p>\n<p><span style=\"font-weight: 400\">As I have described above, the Couchbase time series feature requires the JSON document in this specific format:<\/span><\/p>\n<pre class=\"lang:js decode:true \">docid:\u00a0 \"stock:XYZ:d1\"\r\n{\r\n\u00a0 \"ts_data\": [ [1672531200000, 92.08, 95.62],[1672531201000, 95.62, 99.25],..]\r\n\u00a0 \"ts_start\": 1672531200000 \/* dstart and dend denote the *\/\r\n\u00a0 \"ts_end\": \u00a0 1672617599999,\/* time range of all data points in ts_data *\/\u00a0 \u00a0 \u00a0\r\n\u00a0 \"ticker\": \u00a0 \"XYZ\"\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">Follow the steps below if you need to convert your own time series data into the above format.<\/span><\/p>\n<p><span style=\"font-weight: 400\">The data set used here is for the XYZ Inc stock price for 2013-2015.\u00a0<\/span><\/p>\n<p><b>XYZ_data.csv<\/b><\/p>\n<pre class=\"lang:default decode:true\">date,open,high,low,close,volume,Name\r\n2013-02-08,27.285,27.595,27.24,27.295,5100734,XYZ\r\n2013-02-11,27.64,27.95,27.365,27.61,8916290,XYZ\r\n2013-02-12,27.45,27.605,27.395,27.545,3866508,XYZ<\/pre>\n<h3><span style=\"font-weight: 400\">Migrate Data into Couchbase time series data structure<\/span><\/h3>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Load the CSV file into a Couchbase collection:<\/span><\/li>\n<\/ol>\n<pre class=\"lang:default decode:true\">cbimport csv --infer-types -c https:\/\/&lt;cluster&gt;:8091 -u &lt;login&gt; -p &lt;password&gt; -d 'file:\/\/XYZ_data.csv' -b 'ts' --scope-collection-exp \"s1.c1\" -g \"#UUID#\"<\/pre>\n<p><span style=\"font-weight: 400\">The import will create a JSON document in collection <em>c1<\/em> for each data point.<\/span><\/p>\n<pre class=\"lang:js decode:true \">{\r\n\u00a0 \u00a0 \"c1\": {\r\n\u00a0 \u00a0 \u00a0 \"Name\": \"XYZ\",\r\n\u00a0 \u00a0 \u00a0 \"close\": 55.99,\r\n\u00a0 \u00a0 \u00a0 \"date\": \"2016-05-25T00:00:00.000Z\",\r\n\u00a0 \u00a0 \u00a0 \"high\": 56.69,\r\n\u00a0 \u00a0 \u00a0 \"low\": 55.7699,\r\n\u00a0 \u00a0 \u00a0 \"open\": 56.47,\r\n\u00a0 \u00a0 \u00a0 \"volume\": 9921707\r\n\u00a0 \u00a0 }\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"c1\": {\r\n\u00a0 \u00a0 \u00a0 \"Name\": \"XYZ\",\r\n\u00a0 \u00a0 \u00a0 \"close\": 31.075,\r\n\u00a0 \u00a0 \u00a0 \"date\": \"2013-06-11T00:00:00.000Z\",\r\n\u00a0 \u00a0 \u00a0 \"high\": 31.47,\r\n\u00a0 \u00a0 \u00a0 \"low\": 30.985,\r\n\u00a0 \u00a0 \u00a0 \"open\": 31.15,\r\n\u00a0 \u00a0 \u00a0 \"volume\": 5540312\r\n\u00a0 \u00a0 }\r\n\u00a0 },\u00a0\u00a0\u2026<\/pre>\n<p><span style=\"font-weight: 400\">2. Use SQL++ to transform the collection <em>c1<\/em> into the time series data structure, then insert into the collection <em>c3:<\/em><\/span><\/p>\n<pre class=\"lang:js decode:true \">INSERT INTO ts.s1.c3 (KEY _k, VALUE _v)\r\nSELECT \"stock:XYZ:2013\" _k,\r\n{\"ticker\": a.Name ,\r\n\u00a0 \"ts_start\" : MIN(STR_TO_MILLIS(a.date)),\r\n\u00a0 \"ts_end\" : MAX(STR_TO_MILLIS(a.date)),\r\n\u00a0 \"ts_data\" : ARRAY_AGG([STR_TO_MILLIS(a.date), a.close]) } _v\u00a0\r\nFROM ts.s1.c1 a\r\nWHERE a.date BETWEEN \"2013-01-01\" AND \"2013-12-31\"\r\nGROUP BY a.Name;<\/pre>\n<p><span style=\"font-weight: 400\">The SQL++ performs an <em>INSERT SELECT<\/em> and creates a single document with the structure required for Couchbase time series processing. Note that the <em>ts_data<\/em> array contains the entire 2013 daily closing price data points.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">3. Repeat the INSERT\/SELECT for 2014 and 2015.<\/span><\/p>\n<pre class=\"lang:js decode:true\">[\r\n\u00a0 {\r\n\u00a0 \u00a0 \"id\": \"stock:XYZ:2013\",\r\n\u00a0 \u00a0 \"ticker\": \"XYZ\",\r\n\u00a0 \u00a0 \"ts_start\": 1387497600000,\r\n\u00a0 \u00a0 \"ts_end\": 1365465600000,\r\n\u00a0 \u00a0 \"ts_data\": [\r\n\u00a0 \u00a0 \u00a0 [ 1387497600000, 38.67 ],\r\n\u00a0 \u00a0 \u00a0 [ 1380585600000, 36.21 ],\r\n\u00a0 \u00a0 \u00a0 ...]\r\n\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"id\": \"stock:XYZ:2014\",\r\n\u00a0 \u00a0 \"ticker\": \"XYZ\",\r\n\u00a0 \u00a0 \"ts_start\": 1413331200000,\r\n\u00a0 \u00a0 \"ts_end\": 1402444800000,\r\n\u00a0 \u00a0 \"ts_data\": [\r\n\u00a0 \u00a0 \u00a0 [ 1413331200000, 42.59 ],\r\n\u00a0 \u00a0 \u00a0 [ 1399507200000, 36.525],\r\n\u00a0 \u00a0 \u00a0 ...]\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"id\": \"stock:XYZ:2015\",\r\n\u00a0 \u00a0 \"ticker\": \"XYZ\",\r\n\u00a0 \u00a0 \"ts_start\": 1444780800000,\r\n\u00a0 \u00a0 \"ts_end\": 1436313600000,\r\n\u00a0 \u00a0 \"ts_data\": [\r\n\u00a0 \u00a0 \u00a0 [ 1444780800000, 62.92 ],\r\n\u00a0 \u00a0 \u00a0 [ 1421280000000, 46.405],\r\n\u00a0 \u00a0 \u00a0 ...]\r\n\r\n\u00a0 }\r\n]<\/pre>\n<h3><span style=\"font-weight: 400\">Data Ingestion Strategies<\/span><\/h3>\n<p><span style=\"font-weight: 400\">There are several scenarios that you may have for incremental loading of your Time Series JSON documents.<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none\">\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Adding a range of data points as a new JSON document &#8211; For this scenario you can use the above SQL++ INSERT. You just need to ensure that the data points ranges do not overlap existing documents.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Adding a range of data points to <\/span><b>an existing JSON document<\/b><span style=\"font-weight: 400\"> &#8211; Here you have two options:<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Replace the entire document using UPSERT\/SELECT as in the INSERT\/SELECT<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Use Couchbase SDK to append only the new item data points\u00a0<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<pre class=\"lang:js decode:true\">\/\/ Initialize the Couchbase cluster and bucket objects\r\nCluster cluster = CouchbaseCluster.create(\"&lt;cluster&gt;\");\r\nBucket bucket = cluster.openBucket(\"&lt;your_bucket&gt;\");\r\n\r\n\/\/ Specify the document ID and the sub-document path to update\r\nString docId = \"&lt;doc_id&gt;\";\u00a0 \/\/ eg. \"stock:XYZ:2015\"\r\nString path = \"a.ts_data[-1]\"; \/\/ -1 specifies the last element of the array\r\n\r\n\/\/ Create a JSON object representing the new array element to add\r\nJsonObject newElement = JsonObject.create()\r\n\u00a0 \u00a0 .put(\"0\", \"2015-12-31\")\r\n\u00a0 \u00a0 .put(\"1\", 300);\r\n\r\n\/\/ Use the sub-document API to update the array\r\nJsonDocument doc = bucket.get(docId);\r\nif (doc != null) {\r\n\u00a0 \u00a0 bucket.mutateIn(docId)\r\n\u00a0 \u00a0 \u00a0 \u00a0 .arrayAppend(path, newElement)\r\n\u00a0 \u00a0 \u00a0 \u00a0 .execute();\r\n}<\/pre>\n<h3><span style=\"font-weight: 400\">Query the time series data<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Before querying the data, you should create an index. Although this is not absolutely needed as we only have a few documents, even though each document consists of the entire year of the daily stock price.\u00a0<\/span><\/p>\n<pre class=\"lang:default decode:true\">CREATE INDEX ix1 ON c3(ticker, ts_end, ts_start);<\/pre>\n<p><span style=\"font-weight: 400\">Next we define the range of data that we want the query to run on. Here we define an array with two elements, the start and end epoch time for 2013-01-01 and 2015-12-31.<\/span><\/p>\n<pre class=\"lang:default decode:true \">\\set -$ts_ranges [1682947800000,1685563200000];<\/pre>\n<h3><span style=\"font-weight: 400\">View the time series data points<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Use the <em>_timeseries<\/em> function as described above:<\/span><\/p>\n<pre class=\"lang:default decode:true \">SELECT t.* FROM c3 AS d\r\n\u00a0 UNNEST _timeseries(d, {\"ts_ranges\":$ts_ranges}) AS t\r\nWHERE d.ticker = 'XYZ' AND (d.ts_start &lt;= $ts_ranges[1] AND d.ts_end &gt;= $ts_ranges[0]);<\/pre>\n<p><b>Results:<\/b><\/p>\n<pre class=\"lang:js decode:true\">[\r\n\u00a0 { \"_t\": 1413331200000, \"_v0\": 42.59 },\r\n\u00a0 { \"_t\": 1399507200000, \"_v0\": 36.525},\r\n\u00a0 { \"_t\": 1392854400000, \"_v0\": 37.79 },\r\n\u00a0 { \"_t\": 1395100800000, \"_v0\": 39.82 },\r\n\u00a0 { \"_t\": 1410307200000, \"_v0\": 41.235},\u00a0\u00a0\u2026\u00a0\u00a0]<\/pre>\n<h3><span style=\"font-weight: 400\">View the time series data with SQL++ Window function<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Now that we can access the entire data set, we can use Couchbase SQL++ windows function to run a few advanced aggregation functions. This query returns the daily average for the stock, as well as a 7 day moving average.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<pre class=\"lang:default decode:true \">SELECT MILLIS_TO_TZ(day*86400000,\"UTC\") AS day, dayavg , AVG(dayavg) OVER (ORDER BY day ROWS 7 PRECEDING) AS sevendaymovavg\r\nFROM ts.s1.c3 AS d\r\nUNNEST _timeseries(d, {\"ts_ranges\":$ts_ranges}) AS t\r\nWHERE d.ticker = 'XYZ'\r\n\u00a0\u00a0\u00a0\u00a0  <span style=\"font-weight: 400\">\u00a0\u00a0AND (d.ts_start &lt;= $ts_ranges[<\/span><span style=\"font-weight: 400\">1<\/span><span style=\"font-weight: 400\">] AND d.ts_end &gt;= $ts_ranges[<\/span><span style=\"font-weight: 400\">0<\/span><span style=\"font-weight: 400\">])<\/span>\r\nGROUP BY IDIV(t._t,86400000) AS day\r\nLETTING dayavg = AVG(t._v0);<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Results:<\/strong><\/p>\n<pre class=\"lang:js decode:true\">[\r\n\u00a0 {\r\n\u00a0 \u00a0 \"day\": \"2014-01-02T00:00:00Z\",\r\n\u00a0 \u00a0 \"dayavg\": 39.12,\r\n\u00a0 \u00a0 \"sevendaymovavg\": 39.12\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"day\": \"2014-01-03T00:00:00Z\",\r\n\u00a0 \u00a0 \"dayavg\": 39.015,\r\n\u00a0 \u00a0 \"sevendaymovavg\": 39.067499999999995\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"day\": \"2014-01-06T00:00:00Z\",\r\n\u00a0 \u00a0 \"dayavg\": 38.715,\r\n\u00a0 \u00a0 \"sevendaymovavg\": 38.949999999999996\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"day\": \"2014-01-07T00:00:00Z\",\r\n\u00a0 \u00a0 \"dayavg\": 38.745,\r\n\u00a0 \u00a0 \"sevendaymovavg\": 38.89875\r\n\u00a0 },\r\n\u00a0 {\r\n\u00a0 \u00a0 \"day\": \"2014-01-08T00:00:00Z\",\r\n\u00a0 \u00a0 \"dayavg\": 38.545,\r\n\u00a0 \u00a0 \"sevendaymovavg\": 38.827999999999996\r\n\u00a0 },\r\n\u00a0 ..\r\n]<\/pre>\n<h3><span style=\"font-weight: 400\">Use SQL++ charting on time series data<\/span><\/h3>\n<p><span style=\"font-weight: 400\">In this example, we use the Couchbase Time Series feature and its Charting capability to track a popular trading strategy by tracking fast (5 day) moving averages against slow (30 day) moving averages.<\/span><\/p>\n<pre class=\"lang:default decode:true\">SELECT MILLIS_TO_TZ(day*86400000,\"UTC\") AS day, dayavg ,\r\nAVG(dayavg) OVER (ORDER BY day ROWS 5 PRECEDING) AS fma,\r\nAVG(dayavg) OVER (ORDER BY day ROWS 30 PRECEDING) AS sma\r\nFROM ts.s1.c3 AS d\r\nUNNEST _timeseries(d, {\"ts_ranges\":$ts_ranges}) AS t\r\nWHERE d.ticker = 'XYZ'\r\n<span style=\"font-weight: 400\">  AND (d.ts_start &lt;= $ts_ranges[<\/span><span style=\"font-weight: 400\">1<\/span><span style=\"font-weight: 400\">] AND d.ts_end &gt;= $ts_ranges[<\/span><span style=\"font-weight: 400\">0<\/span><span style=\"font-weight: 400\">])<\/span>\r\nGROUP BY IDIV(t._t,86400000) AS day\r\nLETTING dayavg = AVG(t._v0);<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-14655\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/06\/image2-2-1024x904.png\" alt=\"\" width=\"900\" height=\"795\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image2-2-1024x904.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image2-2-300x265.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image2-2-768x678.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image2-2-1536x1355.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image2-2-1320x1165.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image2-2.png 1854w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<p><span style=\"font-weight: 400\">The idea behind this strategy is to identify when the short term trend (FMA) is crossing above or below the long term (SMA). When the FMA crossed the SMA, it is considered a buy signal, and conversely a sell signal when the FMA crossed below the SMA.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Use SQL++ Common Table Expression with time series data<\/span><\/h3>\n<p><span style=\"font-weight: 400\">This analysis calculates the Relative Strength Index, i.e., the speed and change of the stock price movements to identify when a stock is overbought or sold. An RSI value &gt; 70 may indicate that the stock is overbought and due for correction. Conversely, when the RSI &lt; 30, it may indicate that the stock is oversold and due for a rebound.<\/span><\/p>\n<pre class=\"lang:default decode:true \">WITH price_change AS (\r\nSELECT\u00a0 t._t as date,\r\n\u00a0 \u00a0 \u00a0 \u00a0 t._v0 AS price,\r\n\u00a0 \u00a0 \u00a0 \u00a0 LAG(t._v0, 1) OVER (ORDER BY t._t) AS prev_price,\r\n\u00a0 \u00a0 \u00a0 \u00a0 ROW_NUMBER() OVER (ORDER BY t._t) AS rn\r\nFROM ts.s1.c3 AS d\r\nUNNEST _timeseries(d, {\"ts_ranges\":$ts_ranges}) AS t\r\nWHERE d.ticker = 'XYZ'\r\n\u00a0 AND (\u00a0 $ts_ranges[0] BETWEEN d.ts_start AND d.ts_end\r\n\u00a0 \u00a0 \u00a0 OR (d.ts_start BETWEEN $ts_ranges[0] AND $ts_ranges[1] AND d.ts_end BETWEEN $ts_ranges[0] AND $ts_ranges[1] )\r\n\u00a0 \u00a0 \u00a0 OR $ts_ranges[1] BETWEEN d.ts_start AND d.ts_end\r\n\u00a0 \u00a0 \u00a0 )\r\n),\r\ngain_loss AS (\r\n\u00a0 SELECT pc.date, pc.price, pc.prev_price,\r\n\u00a0 \u00a0 \u00a0 \u00a0 CASE WHEN pc.price &gt; pc.prev_price THEN pc.price - pc.prev_price ELSE 0 END AS gain,\r\n\u00a0 \u00a0 \u00a0 \u00a0 CASE WHEN pc.price &lt; pc.prev_price THEN pc.prev_price - pc.price ELSE 0 END AS loss,\r\n\u00a0 \u00a0 \u00a0 \u00a0 pc.rn\r\n\u00a0 FROM price_change pc\r\n),\r\navg_gain_loss AS (\r\n\u00a0 SELECT gl.date,\r\n\u00a0 \u00a0 \u00a0 \u00a0 AVG(gl.gain) OVER (ORDER BY gl.rn ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) AS avg_gain,\r\n\u00a0 \u00a0 \u00a0 \u00a0 AVG(gl.loss) OVER (ORDER BY gl.rn ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) AS avg_loss,\r\n\u00a0 \u00a0 \u00a0 \u00a0 gl.rn\r\n\u00a0 FROM gain_loss gl\r\n),\r\nrsi AS (\r\n\u00a0 SELECT agl.date,\r\n\u00a0 \u00a0 \u00a0 \u00a0 100 - (100 \/ (1 + (agl.avg_gain \/ agl.avg_loss))) AS rsi_val\r\n\u00a0 FROM avg_gain_loss agl\r\n\u00a0 WHERE agl.rn &gt;= 14\r\n),\r\nbuy_sell_signals AS (\r\n\u00a0 SELECT rsi.date, rsi.rsi_val,\r\n\u00a0 \u00a0 \u00a0 \u00a0 CASE WHEN rsi.rsi_val &lt; 30 THEN 'buy'\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 WHEN rsi.rsi_val &gt; 70 THEN 'sell'\r\n\u00a0 \u00a0 \u00a0 \u00a0 END AS signal\r\n\u00a0 FROM rsi\r\n)\r\nSELECT * FROM buy_sell_signals bss WHERE bss.signal IS NOT NULL;<\/pre>\n<p><span style=\"font-weight: 400\"><strong>Results:<\/strong><\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<pre class=\"lang:default decode:true\">day \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 rsi_val \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 signal\r\n\"2014-01-22T00:00:00Z\" 11.147540983606476 \"buy\"\r\n\"2014-01-23T00:00:00Z\" 9.898107714701524 \u00a0 \u00a0 \u00a0 \"buy\"\r\n\"2014-01-24T00:00:00Z\" 8.785529715762195 \u00a0 \u00a0 \u00a0 \"buy\"\r\n\"2014-01-27T00:00:00Z\" 12.584573748308443 \"buy\"\r\n\"2014-01-28T00:00:00Z\" 20.638820638820576 \"buy\"\r\n\"2014-01-29T00:00:00Z\" 19.354838709677352 \"buy\"\r\n\"2014-02-24T00:00:00Z\" 90.84507042253534 \u00a0 \u00a0 \u00a0 \"sell\"\r\n\"2014-02-25T00:00:00Z\" 95.1306413301663 \u00a0 \u00a0 \u00a0 \"sell\"\r\n\"2014-02-26T00:00:00Z\" 95.25462962962968 \u00a0 \u00a0 \u00a0 \"sell\"\r\n\"2014-02-27T00:00:00Z\" 90.03690036900366 \u00a0 \u00a0 \u00a0 \"sell\"\r\n\"2014-02-28T00:00:00Z\" 88.79668049792528\u00a0 \"sell\"\r\n\"2014-03-03T00:00:00Z\" 79.06403940886698 \u00a0 \u00a0 \u00a0 \"sell\"\r\n\"2014-03-04T00:00:00Z\" 78.8557213930348\u00a0 \"sell\"\r\n\"2014-03-07T00:00:00Z\" 71.54072620215895 \"sell\"\r\n\"2014-03-26T00:00:00Z\" 26.635514018691566 \"buy\"\r\n\"2014-03-27T00:00:00Z\" 17.887029288702877 \"buy\"\r\n\"2014-03-28T00:00:00Z\" 20.75268817204305 \"buy\"\r\n\"2014-03-31T00:00:00Z\" 23.83474576271186 \"buy\"\r\n\"2014-04-01T00:00:00Z\" 26.632653061224502 \"buy\"\r\n\"2014-04-02T00:00:00Z\" 29.02208201892749 \"buy\"\r\n\"2014-04-03T00:00:00Z\" 28.020304568527948 \"buy\"\r\n\"2014-04-04T00:00:00Z\" 20.309477756286242 \"buy\"\r\n\"2014-04-07T00:00:00Z\" 12.318220701454209 \"buy\"\r\n\"2014-04-08T00:00:00Z\" 26.561324303987945 \"buy\"\r\n\"2014-04-09T00:00:00Z\" 29.326574945691576 \"buy\"<\/pre>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2><span style=\"font-weight: 400\">Key Takeaways<\/span><\/h2>\n<p><b>Data Storage <\/b><span style=\"font-weight: 400\">&#8211; The overall data storage for the Couchbase time series will depend how many data points you choose to pack into the array. If analysis is by hour, day, month, then pack the data points according to the period. Note that the storage can also be further reduced if a regular time series is used where the time element in the time series can be derived, and thus does not require storing of the epoch time element.<\/span><\/p>\n<p><b>Data Element and Data Retention with TTL<\/b><span style=\"font-weight: 400\"> &#8211; The maximum size of the JSON document in Couchbase is 20MB. While this could mean you can pack a large number of data points into the time series array, you should also be aware that the Time To Live setting is at the document level, and not the array element level.\u00a0<\/span><\/p>\n<p><b>Data Ingestion <\/b><span style=\"font-weight: 400\">&#8211; Application is responsible for the data ingestion strategy.\u00a0 How to pack the time series data point into the arrays, and array size. Meaning it has to decide whether to append to an existing document, or start a new one.<\/span><\/p>\n<p><span style=\"font-weight: 400\">To learn more, see the <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/time-series.html\"><span style=\"font-weight: 400\">Couchbase time series documentation<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Couchbase is excited to announce the release of a new time-series feature as part of Couchbase 7.2. This feature is built on top of the robust Couchbase distributed database architecture, which is designed to scale horizontally as your data grows, [&hellip;]<\/p>\n","protected":false},"author":26326,"featured_media":14656,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,1819],"tags":[1834,9602,9827],"ppma_author":[8919],"class_list":["post-14594","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-data-modeling","tag-charts","tag-storage","tag-time-series"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Couchbase Time Series: Key Benefits + Use Case Examples<\/title>\n<meta name=\"description\" content=\"As your business grows and your time series data needs increase, Couchbase can effortlessly expand to meet those needs, making it an ideal solution.\" \/>\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\/introducing-couchbase-time-series\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introducing Couchbase Time Series\" \/>\n<meta property=\"og:description\" content=\"As your business grows and your time series data needs increase, Couchbase can effortlessly expand to meet those needs, making it an ideal solution.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-07-26T19:16:39+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-07T19:56:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/06\/image1-2.png\" \/>\n\t<meta property=\"og:image:width\" content=\"907\" \/>\n\t<meta property=\"og:image:height\" content=\"428\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Binh Le\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Binh Le\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/\"},\"author\":{\"name\":\"Binh Le\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/f89064928e262c71eb43bee996c48c63\"},\"headline\":\"Introducing Couchbase Time Series\",\"datePublished\":\"2023-07-26T19:16:39+00:00\",\"dateModified\":\"2024-02-07T19:56:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/\"},\"wordCount\":1735,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image1-2.png\",\"keywords\":[\"charts\",\"storage\",\"time series\"],\"articleSection\":[\"Couchbase Server\",\"Data Modeling\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/\",\"name\":\"Couchbase Time Series: Key Benefits + Use Case Examples\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image1-2.png\",\"datePublished\":\"2023-07-26T19:16:39+00:00\",\"dateModified\":\"2024-02-07T19:56:01+00:00\",\"description\":\"As your business grows and your time series data needs increase, Couchbase can effortlessly expand to meet those needs, making it an ideal solution.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image1-2.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image1-2.png\",\"width\":907,\"height\":428,\"caption\":\"Couchbase time series chart\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introducing Couchbase Time Series\"}]},{\"@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\/f89064928e262c71eb43bee996c48c63\",\"name\":\"Binh Le\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/5b68c37e30928a9d7b2c8470b1a303b7\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g\",\"caption\":\"Binh Le\"},\"description\":\"Binh Le is a Principal Product Manager for Couchbase Query service. Prior to Couchbase, he worked at Oracle and led the product management team for Sales Cloud Analytics and CRM OnDemand. Binh holds a Bachelor's Degree in Computer Science from the University of Brighton, UK.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/binh-le-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Couchbase Time Series: Key Benefits + Use Case Examples","description":"As your business grows and your time series data needs increase, Couchbase can effortlessly expand to meet those needs, making it an ideal solution.","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\/introducing-couchbase-time-series\/","og_locale":"en_US","og_type":"article","og_title":"Introducing Couchbase Time Series","og_description":"As your business grows and your time series data needs increase, Couchbase can effortlessly expand to meet those needs, making it an ideal solution.","og_url":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/","og_site_name":"The Couchbase Blog","article_published_time":"2023-07-26T19:16:39+00:00","article_modified_time":"2024-02-07T19:56:01+00:00","og_image":[{"width":907,"height":428,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/06\/image1-2.png","type":"image\/png"}],"author":"Binh Le","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Binh Le","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/"},"author":{"name":"Binh Le","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/f89064928e262c71eb43bee996c48c63"},"headline":"Introducing Couchbase Time Series","datePublished":"2023-07-26T19:16:39+00:00","dateModified":"2024-02-07T19:56:01+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/"},"wordCount":1735,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image1-2.png","keywords":["charts","storage","time series"],"articleSection":["Couchbase Server","Data Modeling"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/","url":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/","name":"Couchbase Time Series: Key Benefits + Use Case Examples","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image1-2.png","datePublished":"2023-07-26T19:16:39+00:00","dateModified":"2024-02-07T19:56:01+00:00","description":"As your business grows and your time series data needs increase, Couchbase can effortlessly expand to meet those needs, making it an ideal solution.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image1-2.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2023\/06\/image1-2.png","width":907,"height":428,"caption":"Couchbase time series chart"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/introducing-couchbase-time-series\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Introducing Couchbase Time Series"}]},{"@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\/f89064928e262c71eb43bee996c48c63","name":"Binh Le","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/5b68c37e30928a9d7b2c8470b1a303b7","url":"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g","caption":"Binh Le"},"description":"Binh Le is a Principal Product Manager for Couchbase Query service. Prior to Couchbase, he worked at Oracle and led the product management team for Sales Cloud Analytics and CRM OnDemand. Binh holds a Bachelor's Degree in Computer Science from the University of Brighton, UK.","url":"https:\/\/www.couchbase.com\/blog\/author\/binh-le-2\/"}]}},"authors":[{"term_id":8919,"user_id":26326,"is_guest":0,"slug":"binh-le-2","display_name":"Binh Le","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g","author_category":"","last_name":"Le","first_name":"Binh","job_title":"","user_url":"","description":"Binh Le is a Principal Product Manager for Couchbase Query service. Prior to Couchbase, he worked at Oracle and led the product management team for Sales Clould Analytics and CRM OnDemand. Binh holds a Bachelor's Degree in Computer Science from the University of Brighton, UK."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/14594","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\/26326"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=14594"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/14594\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/14656"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=14594"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=14594"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=14594"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=14594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}