@@ -23,6 +23,7 @@ This is the official Cloudant library for Node.js.
2323 * [ Cloudant Geospatial] ( #cloudant-geospatial )
2424 * [ TypeScript Support] ( #typescript-support )
2525 * [ Advanced Features] ( #advanced-features )
26+ * [ Partitioned Databases] ( #partitioned-databases )
2627 * [ Debugging] ( #debugging )
2728 * [ Advanced Configuration] ( #advanced-configuration )
2829 * [ TLS 1.2 Support] ( #tls-12-support )
@@ -876,6 +877,219 @@ See [here](https://www.typescriptlang.org) for further details.
876877
877878## Advanced Features
878879
880+ ### Partitioned Databases
881+
882+ Partitioned databases introduce the ability for a user to create logical groups
883+ of documents called partitions by providing a partition key with each document.
884+
885+ Ensure your Cloudant cluster has the partitions feature enabled. A full list of
886+ enabled features can be retrieved by calling the Cloudant ` ping ()` method.
887+
888+ ` ` ` js
889+ cloudant .ping ().then ((body ) => { console .log (body .features_flags ) })
890+ // [ 'partitioned' ]
891+ ` ` `
892+
893+ **Creating a partitioned database**
894+
895+ ` ` ` js
896+ await cloudant .db .create (' my-partitioned-db' , { partitioned: true })
897+ // { ok: true }
898+ ` ` `
899+
900+ **Handling documents**
901+
902+ The document ID contains both the partition key and document key in the form
903+ ` < partitionkey> : < documentkey> ` where:
904+
905+ - Partition Key *(string)*. Must be non-empty. Must not contain colons (as this
906+ is the partition key delimiter) or begin with an underscore.
907+ - Document Key *(string)*. Must be non-empty. Must not begin with an underscore.
908+
909+ Be aware that ` _design` documents and ` _local` documents must not contain a
910+ partition key as they are global definitions.
911+
912+ *Create a document*
913+
914+ ` ` ` js
915+ // document to add
916+ const doc = { _id: ' canidae:dog' , name: ' Dog' , latin: ' Canis lupus familiaris' }
917+
918+ // insert the document
919+ await db .insert (doc)
920+ // { "ok": true, "id": "canidae:dog", "rev": "1-3a4c4c5d65709bcb3ec675ec895d4051" }
921+ ` ` `
922+
923+ *Get a document*
924+
925+ ` ` ` js
926+ // fetch a document by its ID
927+ await db .get (' canidae:dog' )
928+ // { _id: 'canidae:dog', _rev: '1-3a4c4c5d65709bcb3ec675ec895d4051', name: 'Dog', latin: 'Canis lupus familiaris' }
929+ ` ` `
930+
931+ **Get partition information**
932+
933+ To fetch the information about a single partition, use the ` partitionInfo`
934+ function and pass a partition key:
935+
936+ ` ` ` js
937+ // get partition information from the 'canidae' partition
938+ await db .partitionInfo (' canidae' )
939+ // {"db_name":"myhost-bluemix/mypartitioneddb","sizes":{"active":392,"external":332},"partition":"canidae","doc_count":4,"doc_del_count":0}
940+ ` ` `
941+
942+ **Get all documents from a partition**
943+
944+ To fetch all of the documents from a partition, use the ` partitionedList`
945+ function:
946+
947+ ` ` ` js
948+ // fetch all documents in the 'canidae' partition, returning document bodies too.
949+ await db .partitionedList (' canidae' , { include_docs: true })
950+ // { "total_rows": 4, "offset": 0, "rows": [ ... ] }
951+ ` ` `
952+
953+ **Partitioned Cloudant Query**
954+
955+ :exclamation: To run partitioned queries the database itself must be partitioned. :exclamation:
956+
957+ *Create a partitioned index*
958+
959+ To create an index that is partitioned, ensure that the ` partitioned: true `
960+ field is set when calling the ` insert` function, to instruct Cloudant to create
961+ a partitioned query, instead of a global one:
962+
963+ ` ` ` js
964+ // index definition
965+ const i = {
966+ ddoc: ' partitioned-query' ,
967+ index: { fields: [' name' ] },
968+ name: ' name-index' ,
969+ partitioned: true ,
970+ type: ' json'
971+ }
972+
973+ // instruct Cloudant to create the index
974+ await db .index (i)
975+ // { result: 'created', id: '_design/partitioned-query', name: 'name-index' }
976+ ` ` `
977+
978+ *Find within a partition*
979+
980+ To perform a Cloudant Query in a single partition, use the ` partitionedFind` (or
981+ ` partitionedFindAsStream` ) function:
982+
983+ ` ` ` js
984+ // find document whose name is 'wolf' in the 'canidae' partition
985+ await db .partitionedFind (' canidae' , { ' selector' : { ' name' : ' Wolf' }})
986+ // { "docs": [ ... ], "bookmark": "..." }
987+ ` ` `
988+
989+ **Partitioned Search**
990+
991+ :exclamation: To run partitioned searches the database itself must be partitioned. :exclamation:
992+
993+ *Create a partitioned search index*
994+
995+ To create a [Cloudant
996+ Search](https://cloud.ibm.com/docs/services/Cloudant?topic=cloudant-search)
997+ index that is partitioned, write a [design
998+ document](https://cloud.ibm.com/docs/services/Cloudant?topic=cloudant-design-documents)
999+ to the database containing the index definition. Use ` options .partitioned =
1000+ true ` to specify that this is a partitioned index:
1001+
1002+ ` ` ` js
1003+ // the search definition
1004+ const func = function (doc ) {
1005+ index (' name' , doc .name )
1006+ index (' latin' , doc .latin )
1007+ }
1008+
1009+ // the design document containing the search definition function
1010+ const ddoc = {
1011+ _id: ' _design/search-ddoc' ,
1012+ indexes: {
1013+ search- index: {
1014+ index: func .toString ()
1015+ }
1016+ },
1017+ options: {
1018+ partitioned: true
1019+ }
1020+ }
1021+
1022+ await db .insert (ddoc)
1023+ // { ok: true, id: '_design/search-ddoc', rev: '1-e7257e575d666ca062b4fe0bdeb6fba1' }
1024+ ` ` `
1025+
1026+ *Search within a partition*
1027+
1028+ To perform a [Cloudant
1029+ Search](https://cloud.ibm.com/docs/services/Cloudant?topic=cloudant-search)
1030+ against a pre-existing Cloudant Search index, use the ` partitionedSearch`
1031+ function:
1032+
1033+ ` ` ` js
1034+ const params = {
1035+ q: ' name:\' Wolf\' '
1036+ }
1037+ await db .partitionedSearch (' canidae' , ' search-ddoc' , ' search-index' , params)
1038+ // { total_rows: ... , bookmark: ..., rows: [ ...] }
1039+ ` ` `
1040+
1041+ **MapReduce Views**
1042+
1043+ :exclamation: To run partitioned views the database itself must be partitioned. :exclamation:
1044+
1045+ *Creating a partitioned MapReduce view*
1046+
1047+ To create a MapReduce view, ensure the ` options .partitioned ` flag is set to
1048+ ` true ` to indicate to Cloudant that this is a partitioned rather than a global
1049+ view:
1050+
1051+ ` ` ` js
1052+ const func = function (doc ) {
1053+ emit (doc .family , doc .weight )
1054+ }
1055+
1056+ // Design Document
1057+ const ddoc = {
1058+ _id: ' _design/view-ddoc' ,
1059+ views: {
1060+ family- weight: {
1061+ map: func .toString (),
1062+ reduce: ' _sum'
1063+ }
1064+ },
1065+ options: {
1066+ partitioned: true
1067+ }
1068+ }
1069+
1070+ // create design document
1071+ await db .insert (ddoc)
1072+ // { ok: true, id: '_design/view-ddoc', rev: '1-a062b4fe0bdeb6fbe7257e575d666ca1' }
1073+ ` ` `
1074+
1075+ *Querying a partitioned MapReduce view*
1076+
1077+ To direct a query to a pre-existing partitioned MapReduce view, use the
1078+ ` partitionedView` (or ` partitionedViewAsStream` ) function:
1079+
1080+ ` ` ` js
1081+ const params = {}
1082+ await db .partitionedView (' canidae' , ' view-ddoc' , ' family-weight' , params)
1083+ // { rows: [ { key: ... , value: [Object] } ] }
1084+ ` ` `
1085+
1086+ **Global indexes**
1087+
1088+ A partitioned database may still have *global* Cloudant Query, Cloudant Search
1089+ and MapReduce indexes. Create the indexes as normal but be sure to supply
1090+ ` false ` as the ` partitioned` flag, to indicate you need a global index. Then
1091+ query your index as normal using ` db .find ` , ` db .search ` or ` db .view ` .
1092+
8791093### Debugging
8801094
8811095Enable debugging output by setting the following environment variable:
0 commit comments