Mass data is typically stored in a structure functionally similar to a spreadsheet.
Each separate column of the spreadsheet is exclusively one type of data (with each field directly beneath it holding different entries of that same type), while the rows determine the specific entry.
Combine a column’s “type” with the row’s “index”, and you have the particular piece of data about which you care.
ThingWorx mass data storage functions in roughly the same way. However, ThingWorx does have one differentiation from many spreadsheet implementations.
In ThingWorx, the type that defines each column is not held internally to the data structure itself. Instead, it is abstracted out as a Data Shape.
A Data Shape is the definition of what each column contains.
A Stream requires a Data Shape in order to define its structure.
Create Data Shape
- On the ThingWorx Composer Browse tab, click Modeling -> Data Shapes, + New.
![Data17.png Data17.png](https://community.ptc.com/t5/image/serverpage/image-id/68667i27DDE93F2E8603FA/image-size/large?v=v2&px=999)
- In the Name field, enter Test_Data_Shape.
![Data18.png Data18.png](https://community.ptc.com/t5/image/serverpage/image-id/68668i8AAF796EE201575B/image-size/large?v=v2&px=999)
- If Project is not already set, search for and select PTCDefaultProject.
- At the top, click Field Definitions.
![data19.png data19.png](https://community.ptc.com/t5/image/serverpage/image-id/68669i21AD1883D7CA1F18/image-size/large?v=v2&px=999)
- Click + Add.
- On the right in the Name field, enter Index_Field
. - Change the Base Type to INTEGER.
Check the Is Primary Key checkbox.
- All Data Shapes must have a Primary Key, and Index_Field is an appropriate choice, as it will keep track of the number of entries.
![Data20.png Data20.png](https://community.ptc.com/t5/image/serverpage/image-id/68670iB144E7D1587138C1/image-size/large?v=v2&px=999)
- At the top-right, click the "Check with a +" button for Done and Add.
- In the Name field, enter Value_Field.
- Change the Base Type to NUMBER.
![Data21.png Data21.png](https://community.ptc.com/t5/image/serverpage/image-id/68671iE0410D60902BB71B/image-size/large?v=v2&px=999)
- At the top-right, click the "Check" button for Done.
- At the top, click Save.
![Data22.png Data22.png](https://community.ptc.com/t5/image/serverpage/image-id/68672iC8440B7198D88B4D/image-size/large?v=v2&px=999)
Once again, the Data Shape does nothing by itself.
It simply defines that some other mass data structure (such as a Stream) follows the particular format of the Data Shape.
So a Stream assigned the Test_Data_Shape above would have two fields per entry, i.e. an Index and a Value.
Create Stream
Streams are a mass data storage option optimized for Time-Series data.
They are utilized in much the same way as Value Streams, but possess additional functionality.
For one, Streams do not have to be tied to Things in the way that Value Streams are. They can be entirely independent, or even accept inputs from multiple different Things.
This can be useful when you want to have a master list of what every similar Thing was doing at particular points throughout some timeframe.
- On the ThingWorx Composer Browse tab, click DATA STORAGE -> Streams, + New.
![Stream1.png Stream1.png](https://community.ptc.com/t5/image/serverpage/image-id/70205iAFE8E215E263A0BD/image-size/large?v=v2&px=999)
- On the Choose Template pop-up, select Stream and click OK.
![Stream2.png Stream2.png](https://community.ptc.com/t5/image/serverpage/image-id/70206i8EFBC5B6C5DE26C5/image-size/large?v=v2&px=999)
- In the Name field, enter Test_Stream.
![Stream3.png Stream3.png](https://community.ptc.com/t5/image/serverpage/image-id/70207i97EAA0067E5E4495/image-size/large?v=v2&px=999)
- If Project is not already set, search for and select PTCDefaultProject.
- In the Data Shape field, search for and select Test_Data_Shape.
- At the top, click Save.
![Stream4.png Stream4.png](https://community.ptc.com/t5/image/serverpage/image-id/70208iCA74FC2BB4EEB66D/image-size/large?v=v2&px=999)
Create Thing
Now that the Stream is created, you'll create a Thing from which you can log some Properties.
- On the ThingWorx Composer Browse tab, click MODELING -> Things, + New.
![Stream5.png Stream5.png](https://community.ptc.com/t5/image/serverpage/image-id/70210iCB60BF6AAA47076A/image-size/large?v=v2&px=999)
- In the Name field, enter Stream_Test_Thing.
- If Project is not already set, search for and select PTCDefaultProject.
- In the Thing Template field, search for and select GenericThing.
![Stream6.png Stream6.png](https://community.ptc.com/t5/image/serverpage/image-id/70211i4D5553B986CB467A/image-size/large?v=v2&px=999)
- At the top, click Properties and Alerts.
![Stream7.png Stream7.png](https://community.ptc.com/t5/image/serverpage/image-id/70212i17B9872BE7267175/image-size/large?v=v2&px=999)
- Click + Add.
- In the Name field, enter Index_Property.
- Change the Base Type to Integer.
- Check the Persistent checkbox.
![Stream8.png Stream8.png](https://community.ptc.com/t5/image/serverpage/image-id/70213i50BE83A39533678B/image-size/large?v=v2&px=999)
- At the top-right, click the "Check with a +" button for Done and Add.
- In the Name field, enter Value_Property.
- Change the Base Type to Number.
- Check the Persistent checkbox.
![Stream9.png Stream9.png](https://community.ptc.com/t5/image/serverpage/image-id/70214iA3ABED8C7EDA7E28/image-size/large?v=v2&px=999)
- At the top-right, click the "Check" button for Done.
Add Service
Since you now have both a Thing and a Stream, we can write a Service which logs the Properties' values when the Service is executed.
- At the top, click Services.
![Stream10.png Stream10.png](https://community.ptc.com/t5/image/serverpage/image-id/70215i0E70988D498C4C61/image-size/large?v=v2&px=999)
- At the top, click + Add.
- In the Name field, enter Add_Stream_Entry_Service.
![Stream11.png Stream11.png](https://community.ptc.com/t5/image/serverpage/image-id/70216i0BB1B0F949A82620/image-size/large?v=v2&px=999)
- On the left under New Service, click the Snippets tab.
![Stream12.png Stream12.png](https://community.ptc.com/t5/image/serverpage/image-id/70217i3241EEE6ED4EE8EC/image-size/large?v=v2&px=999)
- In the Filter field, type add str.
![Stream13.png Stream13.png](https://community.ptc.com/t5/image/serverpage/image-id/70218i56613E8917590F41/image-size/large?v=v2&px=999)
- Expand the Stream, Blog, Data Table section to reveal the Add Stream Entry Snippet.
![Stream14.png Stream14.png](https://community.ptc.com/t5/image/serverpage/image-id/70219i41809D7030C1A920/image-size/large?v=v2&px=999)
Click the right arrow beside Add Stream Entry.
- An Add Stream Entry pop-up will open.
![Stream15.png Stream15.png](https://community.ptc.com/t5/image/serverpage/image-id/70220iA421D1B16475DB97/image-size/large?v=v2&px=999)
- In the Search Streams field, enter test.
![Stream16.png Stream16.png](https://community.ptc.com/t5/image/serverpage/image-id/70221iCE08D5FA081AF4CF/image-size/large?v=v2&px=999)
- Select Test_Stream.
![Stream17.png Stream17.png](https://community.ptc.com/t5/image/serverpage/image-id/70222i769E2A921DB86D45/image-size/large?v=v2&px=999)
Click the Insert Code Snippet button.
- Note that a section of Javascript code has now been added to the Script window.
![Stream18.png Stream18.png](https://community.ptc.com/t5/image/serverpage/image-id/70223i313FEAA95EE84BD7/image-size/large?v=v2&px=999)
Modify Snippet
The inserted Javascript Snippet has already done most of the work of creating a custom Service for us.
All which you need to do now is modify the code Snippet to store the particular Property values from your Thing.
- On the 10th line of code, double-click undefined to select it.
![Stream19.png Stream19.png](https://community.ptc.com/t5/image/serverpage/image-id/70224iC25713AFEAB3F2AC/image-size/large?v=v2&px=999)
- On the left, click the Me/Entities tab.
![Stream20.png Stream20.png](https://community.ptc.com/t5/image/serverpage/image-id/70225iB70E9EC8ADA3BD7B/image-size/large?v=v2&px=999)
Under the Me/Entities tab, expand Properties.
- Note that this is not the Properties and Alerts at the top of Composer.
![Stream21.png Stream21.png](https://community.ptc.com/t5/image/serverpage/image-id/70226i9BF39D30FEEBDCD3/image-size/large?v=v2&px=999)
Click the right arrow beside Value_Property.
- Note that undefined has been replaced by me.Value_Property.
![Stream22.png Stream22.png](https://community.ptc.com/t5/image/serverpage/image-id/70227i8FBE8E70F10AD69E/image-size/large?v=v2&px=999)
- On the 11th line of code, double-click the remaining undefined to select it.
![Stream24.png Stream24.png](https://community.ptc.com/t5/image/serverpage/image-id/70229i6C436AC858E4325A/image-size/large?v=v2&px=999)
Click the right arrow beside Index_Property.
- Note that the second “undefined” has been replaced by “me.Index_Property”.
![Stream25.png Stream25.png](https://community.ptc.com/t5/image/serverpage/image-id/70230iFB280CD6E8F0B555/image-size/large?v=v2&px=999)
- At the top, click Done to close the Add_Stream_Entry_Service editing window.
![Stream26.png Stream26.png](https://community.ptc.com/t5/image/serverpage/image-id/70231iE3AE50A03491C5A0/image-size/large?v=v2&px=999)
- At the top, click Save.
Click here to view Part 3 of this guide.