/// <summary>
        /// Initializes the partition resolver to be used with Item repository.
        /// </summary>
        /// <param name="resolverService"></param>
        public async void getResolver(int resolverService)
        {
            switch (resolverService)
            {
            case Hash:
                HashPartitionResolver hashResolver = await PartitionInitializers.InitializeHashResolver("tenantId", Client, Database, collections);

                break;

            case ManagedHash:
                ManagedHashPartitionResolver managedHashResolver = PartitionInitializers.InitializeManagedHashResolver(i => ((Item)i).tenantId, Client, Database, 3, null);
                break;

            case Spillover:
                SpilloverPartitionResolver spilloverResolver = new SpilloverPartitionResolver(Client, Database);
                Client.PartitionResolvers[Database.SelfLink] = spilloverResolver;
                break;

            case Range:
                RangePartitionResolver <string> rangeResolver = await PartitionInitializers.InitializeRangeResolver("tenantId", Client, Database, collections);

                break;

            case Lookup:
                LookupPartitionResolver <string> lookupResolver = await PartitionInitializers.InitializeLookupPartitionResolver("tenantId", Client, Database, collections);

                break;

            default:
                goto case Hash;
            }
        }
        public static async Task RunAsync(string[] args)
        {
            var client   = DocumentDbExtension.CreateClient();
            var database = await client.GetDatabaseAsync("IoTEvents");

            var temperatureSamplesNorth = await client.GetCollectionAsync(database, "temperatureSamplesNorth");

            var temperatureSamplesMiddle = await client.GetCollectionAsync(database, "temperatureSamplesMiddle");

            var temperatureSamplesSouth = await client.GetCollectionAsync(database, "temperatureSamplesSouth");

            RangePartitionResolver <string> regionResolver = new RangePartitionResolver <string>(
                "RegionName",
                new Dictionary <Range <string>, string>()
            {
                { new Range <string>("North"), temperatureSamplesNorth.SelfLink },
                { new Range <string>("Middle"), temperatureSamplesMiddle.SelfLink },
                { new Range <string>("South"), temperatureSamplesSouth.SelfLink }
            }
                );

            client.PartitionResolvers[database.SelfLink] = regionResolver;

            //var response = await client.NewTemperatureSampleDocumentAsync(database.SelfLink, "Pordenone", Region.North, 45, 12, Guid.NewGuid(), SensorClass.A, 24);
            //response = await client.NewTemperatureSampleDocumentAsync(database.SelfLink, "Roma", Region.Middle, 45, 12, Guid.NewGuid(), SensorClass.B, 25);
            //response = await client.NewTemperatureSampleDocumentAsync(database.SelfLink, "Napoli", Region.South, 45, 12, Guid.NewGuid(), SensorClass.C, 26);

            var query  = client.CreateDocumentQuery <TemperatureSample>(database.SelfLink, null, "Middle");
            var sample = query.AsEnumerable().FirstOrDefault();


            Console.ReadLine();
        }
示例#3
0
        private static RangePartitionResolver<long> GetUpdateResolver(RangePartitionResolver<long> oldResolver,
            DocumentCollection newDc)
        {
            var map = new Dictionary<Range<long>, string>();
            var vs = oldResolver.PartitionMap;
            if (vs.Count > 1)
            {
                foreach (var v in vs)
                {
                    if (map.Count < vs.Count - 1)
                    {
                        map.Add(new Range<long>(v.Key.Low, v.Key.High), v.Value);
                    }
                }
            }
            //Check Resolver
            var now = (long) (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
            if (now < vs.LastOrDefault().Key.Low || now > vs.LastOrDefault().Key.High) return null;

            map.Add(new Range<long>(vs.LastOrDefault().Key.Low, now), vs.LastOrDefault().Value);
            map.Add(new Range<long>(now + 1, vs.LastOrDefault().Key.High), newDc.SelfLink);
            return new RangePartitionResolver<long>(
                u => ((PostMessage) u).Info.timestamp,
                map);
        }
        public async Task <IHttpActionResult> RangePartitionResolver()
        {
            string[] collections = AppSettingsConfig.MainCollection.Split(',');
            var      database    = await DocumentClientHelper.GetNewDatabaseAsync(_client, AppSettingsConfig.Db);

            RangePartitionResolver <string> rangeResolver = await PartitionInitializers.InitializeRangeResolver("UserId", _client, database, collections);

            return(Ok());
        }
示例#5
0
        /// <summary>
        /// Initialize a RangePartitionResolver.
        /// </summary>
        /// <param name="partitionKeyPropertyName">The property name to be used as the partition Key.</param>
        /// <param name="client">The DocumentDB client instance to use.</param>
        /// <param name="database">The database to run the samples on.</param>
        /// <param name="collectionNames">The names of collections used.</param>
        /// <returns>The created HashPartitionResolver.</returns>
        public static async Task <RangePartitionResolver <string> > InitializeRangeResolver(string partitionKeyPropertyName, DocumentClient client, Database database, string[] collectionNames)
        {
            // Set local to input.
            string[] CollectionNames    = collectionNames;
            int      numCollectionNames = CollectionNames.Length;

            // Create array of DocumentCollections.
            DocumentCollection[] collections = new DocumentCollection[numCollectionNames];

            // Create string array of Self Links to Collections.
            string[] selfLinks = new string[numCollectionNames];

            //Create some collections to partition data.
            for (int i = 0; i < numCollectionNames; i++)
            {
                collections[i] = await DocumentClientHelper.GetCollectionAsync(client, database, CollectionNames[i]);

                selfLinks[i] = collections[i].SelfLink;
            }

            // Join Self Link Array into a comma separated string.
            string selfLinkString = String.Join(", ", selfLinks);

            // If each collection represents a range, it will have both a start and end point in its range, thus there are 2 rangeNames for each collection.
            string[] rangeNames = new string[numCollectionNames * 2];

            // Keeping track of where in the rangeNames array to add a new start/end of a range.
            int currentRangePosition = 0;

            for (int y = 0; y < numCollectionNames; y++)
            {
                string[] rangeTemp = collectionNames[y].Split('-');
                for (int z = 0; z < rangeTemp.Length; z++)
                {
                    rangeNames[currentRangePosition] = rangeTemp[z];
                    currentRangePosition++;
                }
            }

            // Dictionary needed to input into RangePartitionResolver with corresponding range and collection self link.
            Dictionary <Range <string>, string> rangeCollections = new Dictionary <Range <string>, string>();

            // TO DO:: Iterate through the ranges and add then to rangeCollections with the appropriate start/end point, with the corresponding collection self link.
            //rangeCollections.Add()

            RangePartitionResolver <string> rangeResolver = new RangePartitionResolver <string>(
                partitionKeyPropertyName,
                rangeCollections);

            client.PartitionResolvers[database.SelfLink] = rangeResolver;
            return(rangeResolver);
        }
示例#6
0
 private static RangePartitionResolver<long> GenerateResolver(Document q)
 {
     var map = new Dictionary<Range<long>, string>();
     dynamic d = q;
     foreach (var dd in d.resolver.PartitionMap)
     {
         string dz = dd.Name.ToString();
         var l = dz.Split(',');
         map.Add(new Range<long>(Convert.ToInt64(l[0]), Convert.ToInt64(l[1])), dd.Value.ToString());
     }
     var rangeResolver = new RangePartitionResolver<long>(
         u => ((PostMessage) u).Info.timestamp, map);
     return rangeResolver;
 }
示例#7
0
        /// <summary>
        /// Initialize a RangePartitionResolver.
        /// </summary>
        /// <param name="database">The database to run the samples on.</param>
        /// <returns>The created RangePartitionResolver.</returns>
        private async Task <RangePartitionResolver <string> > InitializeRangeResolver(Database database)
        {
            // Create some collections to partition data.
            DocumentCollection collection1 = await DocumentClientHelper.GetCollectionAsync(this.client, database, "Collection.A-M");

            DocumentCollection collection2 = await DocumentClientHelper.GetCollectionAsync(this.client, database, "Collection.N-Z");

            // Initialize a partition resolver that assigns users (A-M) -> collection1, and (N-Z) -> collection2
            // and register with DocumentClient.
            // Note: \uffff is the largest UTF8 value, so M\ufff includes all strings that start with M.
            RangePartitionResolver <string> rangeResolver = new RangePartitionResolver <string>(
                "UserId",
                new Dictionary <Range <string>, string>()
            {
                { new Range <string>("A", "M\uffff"), collection1.SelfLink },
                { new Range <string>("N", "Z\uffff"), collection2.SelfLink },
            });

            this.client.PartitionResolvers[database.SelfLink] = rangeResolver;
            return(rangeResolver);
        }
        /// <summary>
        /// Initialize a RangePartitionResolver.
        /// </summary>
        /// <param name="database">The database to run the samples on.</param>
        /// <returns>The created RangePartitionResolver.</returns>
        private async Task<RangePartitionResolver<string>> InitializeRangeResolver(Database database)
        {
            // Create some collections to partition data.
            DocumentCollection collection1 = await DocumentClientHelper.GetOrCreateCollectionAsync(this.client, database.Id, "Collection.A-M");
            DocumentCollection collection2 = await DocumentClientHelper.GetOrCreateCollectionAsync(this.client, database.Id, "Collection.N-Z");

            // Initialize a partition resolver that assigns users (A-M) -> collection1, and (N-Z) -> collection2
            // and register with DocumentClient. 
            // Note: \uffff is the largest UTF8 value, so M\ufff includes all strings that start with M.
            RangePartitionResolver<string> rangeResolver = new RangePartitionResolver<string>(
                "UserId",
                new Dictionary<Range<string>, string>() 
                { 
                    { new Range<string>("A", "M\uffff"), collection1.SelfLink },
                    { new Range<string>("N", "Z\uffff"), collection2.SelfLink },
                });

            this.client.PartitionResolvers[database.SelfLink] = rangeResolver;
            return rangeResolver;
        }
        static async Task MainAsync(string[] args)
        {
            var endpoint    = ConfigurationManager.AppSettings["DocumentDbEndPoint"];
            var endpointUri = new Uri(endpoint);
            var authKey     = ConfigurationManager.AppSettings["DocumentDbAuthKey"];
            var client      = new DocumentClient(endpointUri, authKey);

            //var adventureWorksLT =
            //    client.CreateDatabaseQuery()
            //    .Where(xx => xx.Id == "AdventureWorksLT")
            //    .ToList()
            //    .FirstOrDefault();

            //var collectionId = "documents";
            //var documents =
            //    client.CreateDocumentCollectionQuery(adventureWorksLT.SelfLink)
            //    .Where(xx => xx.Id == collectionId)
            //    .ToList()
            //    .FirstOrDefault();

            //var collectionLink = documents.SelfLink;

            var databaseUri = new Uri("/dbs/AdventureWorks", UriKind.Relative);
            var documents   =
                client.CreateDocumentCollectionQuery(databaseUri)
                .Where(xx => xx.Id == "documents")
                .ToList()
                .FirstOrDefault();

            documents.IndexingPolicy.IndexingMode = IndexingMode.Lazy;
            documents = await client.ReplaceDocumentCollectionAsync(documents);

            RangePartitionResolver <string> rangeResolver = new RangePartitionResolver <string>(
                p => ((ProductDetailDTO)p).ProductModel.Name,
                new Dictionary <Range <string>, string>()
            {
                { new Range <string>("A", "M\uffff"), "/dbs/AdventureWorksLT/colls/productsA-M" },
                { new Range <string>("N", "Z\uffff"), "/dbs/AdventureWorksLT/colls/productsN-Z" },
            });

            client.PartitionResolvers["/dbs/AdventureWorks"] = rangeResolver;

            var dbContext = new AdventureWorksLTDataModel();
            var products  = dbContext.Product.ToDTO().ToList();
            var i         = 1;

            foreach (var productDto in products)
            {
                var response = await client.CreateDocumentAsync(documents.SelfLink, productDto);

                //var response = await client.CreateDocumentAsync("/dbs/AdventureWorks", productDto);
                Console.Write("{0}", response.Resource.SelfLink);
                Console.WriteLine("...done");
                i++;
            }

            documents.IndexingPolicy.IndexingMode = IndexingMode.Consistent;
            documents.IndexingPolicy.IncludedPaths.Clear();
            // "root"
            var rootPath = new IncludedPath {
                Path = "/"
            };

            rootPath.Indexes.Add(new HashIndex(DataType.String));
            rootPath.Indexes.Add(new HashIndex(DataType.Number));
            documents.IndexingPolicy.IncludedPaths.Add(rootPath);
            // Type
            var typePath = new IncludedPath {
                Path = "/Type/?"
            };

            typePath.Indexes.Add(new HashIndex(DataType.String));
            documents.IndexingPolicy.IncludedPaths.Add(typePath);
            // excluded
            documents.IndexingPolicy.ExcludedPaths.Clear();
            // ProductCategory
            documents.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath {
                Path = "/ProductCategory/*"
            });
            var productCategoryIdPath = new IncludedPath {
                Path = "/ProductCategory/Id/?"
            };

            productCategoryIdPath.Indexes.Add(new HashIndex(DataType.String));
            documents.IndexingPolicy.IncludedPaths.Add(productCategoryIdPath);
            // ProductModel
            documents.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath {
                Path = "/ProductModel/*"
            });
            var productModelIdPath = new IncludedPath {
                Path = "/ProductModel/Id/?"
            };

            productModelIdPath.Indexes.Add(new HashIndex(DataType.String));
            documents.IndexingPolicy.IncludedPaths.Add(productModelIdPath);
            // make effective
            documents = await client.ReplaceDocumentCollectionAsync(documents);
        }
示例#10
0
        public async Task<bool> UpdateResolver(DocumentCollection newDc)
        {
            var client = GetDocumentClient();
            var oldResolver = GetResolver(client);
            if (oldResolver == null) return false;

            var map = new Dictionary<Range<long>, string>();
            var vs = oldResolver.PartitionMap;
            if (vs.Count > 1)
            {
                foreach (var v in vs)
                {
                    if (map.Count < vs.Count - 1)
                    {
                        map.Add(new Range<long>(v.Key.Low, v.Key.High), v.Value);
                    }
                }
            }
            var now = (long) (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
            if (now < vs.LastOrDefault().Key.Low || now > vs.LastOrDefault().Key.High) return false;

            map.Add(new Range<long>(vs.LastOrDefault().Key.Low, now), vs.LastOrDefault().Value);
            map.Add(new Range<long>(now + 1, vs.LastOrDefault().Key.High), newDc.SelfLink);
            var newResolver = new RangePartitionResolver<long>(
                u => ((PostMessage) u).Info.timestamp,
                map);


            var m =
                client.CreateDocumentQuery(_masterCollectionSelfLink)
                    .Where(x => x.Id == "AZresolver")
                    .AsEnumerable()
                    .FirstOrDefault();
            if (m == null) return false;
            await ExecuteWithRetries(() => client.DeleteDocumentAsync(m.SelfLink));
            var res =
                await
                    ExecuteWithRetries(
                        () => client.CreateDocumentAsync(_masterCollectionSelfLink, new RangeResolver
                        {
                            id = "AZresolver",
                            resolver = newResolver
                        }));

            return res.StatusCode == HttpStatusCode.Created;
        }
示例#11
0
        public async Task<bool> InitResolver(string selfLink)
        {
            var masterCollectionSelfLink = _masterCollectionSelfLink;
            if (selfLink != "")
            {
                masterCollectionSelfLink = selfLink;
            }
        
            var client = GetDocumentClient();
            var start = (long) (DateTime.UtcNow.AddDays(-1).Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
            var end = (long) (start + TimeSpan.FromDays(365).TotalMilliseconds);
            var rangeResolver = new RangePartitionResolver<long>(
                u => ((PostMessage) u).Info.timestamp,
                new Dictionary<Range<long>, string>()
                {
                    {new Range<long>(start, end), masterCollectionSelfLink}
                });

            var m =
                client.CreateDocumentQuery(masterCollectionSelfLink)
                    .Where(x => x.Id == "AZresolver")
                    .AsEnumerable()
                    .FirstOrDefault();
            if (m != null)
            {
                await ExecuteWithRetries(() => client.DeleteDocumentAsync(m.SelfLink));
            }
            var res =
                await
                    ExecuteWithRetries(
                        () => client.CreateDocumentAsync(masterCollectionSelfLink, new RangeResolver
                        {
                            id = "AZresolver",
                            resolver = rangeResolver
                        }));

            return res.StatusCode == HttpStatusCode.Created;
        }
示例#12
0
        private static async Task InitializeRangeResolverAsync()
        {
            #region Partition Collection 1

            if (_partitionCollection1 == null)
            {
                // dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentId
                _partitionCollection1 =
                    _documentDbClient.CreateDocumentCollectionQuery("dbs/" + _documentDatabase.Id)
                    .Where(c => c.Id == PartitionCollectionName1)
                    .AsEnumerable()
                    .FirstOrDefault();

                // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
                if (_partitionCollection1 == null)
                {
                    _partitionCollection1 =
                        await _documentDbClient.CreateDocumentCollectionAsync("dbs/" + _documentDatabase.Id,
                                                                              new Db.DocumentCollection
                    {
                        Id             = PartitionCollectionName1,
                        IndexingPolicy =
                        {
                            Automatic    = true,
                            IndexingMode = Db.IndexingMode.Lazy
                        }
                    }, new Db.Client.RequestOptions
                    {
                        OfferType = "S1"
                    });
                }
            }

            #endregion

            #region Partition Collection 2

            if (_partitionCollection2 == null)
            {
                // dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentId
                _partitionCollection2 =
                    _documentDbClient.CreateDocumentCollectionQuery("dbs/" + _documentDatabase.Id)
                    .Where(c => c.Id == PartitionCollectionName2)
                    .AsEnumerable()
                    .FirstOrDefault();

                // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
                if (_partitionCollection2 == null)
                {
                    _partitionCollection2 =
                        await _documentDbClient.CreateDocumentCollectionAsync("dbs/" + _documentDatabase.Id,
                                                                              new Db.DocumentCollection
                    {
                        Id             = PartitionCollectionName2,
                        IndexingPolicy =
                        {
                            Automatic    = true,
                            IndexingMode = Db.IndexingMode.Lazy
                        }
                    }, new Db.Client.RequestOptions
                    {
                        OfferType = "S1"
                    });
                }
            }

            #endregion

            // Initialize a partition resolver that assigns users (A-M) -> collection1, and (N-Z) -> collection2
            // and register with DocumentClient.
            // Note: \uffff is the largest UTF8 value, so M\ufff includes all strings that start with M.
            _rangeResolver = new RangePartitionResolver <string>(
                "UserId",
                new Dictionary <Range <string>, string>()
            {
                { new Range <string>("A", "M\uffff"), _partitionCollection1.SelfLink },
                { new Range <string>("N", "Z\uffff"), _partitionCollection2.SelfLink },
            });

            _documentDbClient.PartitionResolvers[_documentDatabase.SelfLink] = _rangeResolver;
        }
示例#13
0
        /// <summary>
        /// Run samples for Database create, read, update and delete.
        /// </summary>
        /// <returns>a Task object.</returns>
        private async Task RunAsync()
        {
            // Let's see how a to use a HashPartitionResolver.
            Console.WriteLine("Running samples with the default hash partition resolver ...");
            Database database = await DocumentClientHelper.GetNewDatabaseAsync(this.client, DatabaseId);

            HashPartitionResolver hashResolver = await this.InitializeHashResolver(database);

            await this.RunCrudAndQuerySample(database, hashResolver);

            // Let's see how to use a RangePartitionResolver.
            Console.WriteLine("Running samples with the default range partition resolver ...");
            database = await DocumentClientHelper.GetNewDatabaseAsync(this.client, DatabaseId);

            RangePartitionResolver <string> rangeResolver = await this.InitializeRangeResolver(database);

            await this.RunCrudAndQuerySample(database, rangeResolver);

            // Now let's take a look at an example of how to derive from one of the supported partition resolvers.
            // Here we implement a generic hash resolver that takes an arbirary lambda to extract partition keys.
            database = await DocumentClientHelper.GetNewDatabaseAsync(this.client, DatabaseId);

            HashPartitionResolver customHashResolver = await this.InitializeCustomHashResolver(database);

            await this.RunCrudAndQuerySample(database, customHashResolver);

            // Let's take a look at a example of a LookupPartitionResolver, i.e., use a simple lookup table.
            Console.WriteLine("Running samples with a lookup partition resolver ...");
            database = await DocumentClientHelper.GetNewDatabaseAsync(this.client, DatabaseId);

            LookupPartitionResolver <string> lookupResolver = await this.InitializeLookupPartitionResolver(database);

            await this.RunCrudAndQuerySample(database, lookupResolver);

            // Now, a "managed" HashPartitionResolver that creates collections, while cloning their attributes like
            // IndexingPolicy and OfferType.
            Console.WriteLine("Running samples with a custom hash partition resolver that automates creating collections ...");
            database = await DocumentClientHelper.GetNewDatabaseAsync(this.client, DatabaseId);

            ManagedHashPartitionResolver managedHashResolver = this.InitializeManagedHashResolver(database);

            await this.RunCrudAndQuerySample(database, managedHashResolver);

            // Now, a PartitionResolver that starts with one collection and spills over to new ones as the collections
            // get filled up.
            Console.WriteLine("Running samples with a custom \"spillover\" partition resolver");
            database = await DocumentClientHelper.GetNewDatabaseAsync(this.client, DatabaseId);

            SpilloverPartitionResolver spilloverResolver = new SpilloverPartitionResolver(this.client, database);

            this.client.PartitionResolvers[database.SelfLink] = spilloverResolver;
            await this.RunCrudAndQuerySample(database, spilloverResolver);

            // Now let's see how to persist the settings for a PartitionResolver, and how to bootstrap from those settings.
            this.RunSerializeDeserializeSample(hashResolver);

            // Now let's take a look at how to add and remove partitions to a HashPartitionResolver.
            database = await DocumentClientHelper.GetNewDatabaseAsync(this.client, DatabaseId);

            await this.RepartitionDataSample(database);
        }
示例#14
0
        private async Task CheckResolver()
        {
            _iDbService.UpdateDocumentClient();
            while (_run)
            {
                var client = _iDbService.GetDocumentClient();
                var resolver = _iDbService.GetResolver(client);
                if (_resolver.PartitionMap.Count != resolver.PartitionMap.Count)
                {
                    _iDbService.UpdateDocumentClient();
                    _resolver = resolver;
                }

                var curdc = _resolver.PartitionMap.LastOrDefault().Value;
                var res = await client.ReadDocumentCollectionAsync(curdc);
                var rate = res.CollectionSizeUsage/res.CollectionSizeQuota;

                if (rate > 0.8)
                {
                    await Task.Delay(TimeSpan.FromSeconds(10));
                }
                else
                {
                    await Task.Delay(TimeSpan.FromDays(1));
                }
            }
        }
示例#15
0
 public RangePartitionResolver<long> GetResolver(DocumentClient client)
 {
     var q =
         client.CreateDocumentQuery(_masterCollectionSelfLink)
             .Where(x => x.Id == "AZresolver")
             .AsEnumerable()
             .FirstOrDefault();
     if (q == null) return null;
     var map = new Dictionary<Range<long>, string>();
     dynamic d = q;
     foreach (var dd in d.resolver.PartitionMap)
     {
         string dz = dd.Name.ToString();
         var l = dz.Split(',');
         map.Add(new Range<long>(Convert.ToInt64(l[0]), Convert.ToInt64(l[1])), dd.Value.ToString());
     }
     var rangeResolver = new RangePartitionResolver<long>(
         u => ((PostMessage) u).Info.timestamp, map);
     return rangeResolver;
 }
示例#16
0
        private static async Task InitializeRangeResolverAsync()
        {
            #region Partition Collection 1

            if (_partitionCollection1 == null)
            {
                // dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentId              
                _partitionCollection1 =
                    _documentDbClient.CreateDocumentCollectionQuery("dbs/" + _documentDatabase.Id)
                        .Where(c => c.Id == PartitionCollectionName1)
                        .AsEnumerable()
                        .FirstOrDefault();

                // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
                if (_partitionCollection1 == null)
                {
                    _partitionCollection1 =
                        await _documentDbClient.CreateDocumentCollectionAsync("dbs/" + _documentDatabase.Id,
                            new Db.DocumentCollection
                            {
                                Id = PartitionCollectionName1,
                                IndexingPolicy =
                                {
                                    Automatic = true,
                                    IndexingMode = Db.IndexingMode.Lazy
                                }
                            }, new Db.Client.RequestOptions
                            {
                                OfferType = "S1"
                            });
                }
            }

            #endregion

            #region Partition Collection 2

            if (_partitionCollection2 == null)
            {
                // dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentId              
                _partitionCollection2 =
                    _documentDbClient.CreateDocumentCollectionQuery("dbs/" + _documentDatabase.Id)
                        .Where(c => c.Id == PartitionCollectionName2)
                        .AsEnumerable()
                        .FirstOrDefault();

                // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
                if (_partitionCollection2 == null)
                {
                    _partitionCollection2 =
                        await _documentDbClient.CreateDocumentCollectionAsync("dbs/" + _documentDatabase.Id,
                            new Db.DocumentCollection
                            {
                                Id = PartitionCollectionName2,
                                IndexingPolicy =
                                {
                                    Automatic = true,
                                    IndexingMode = Db.IndexingMode.Lazy
                                }
                            }, new Db.Client.RequestOptions
                            {
                                OfferType = "S1"
                            });
                }
            }

            #endregion

            // Initialize a partition resolver that assigns users (A-M) -> collection1, and (N-Z) -> collection2
            // and register with DocumentClient. 
            // Note: \uffff is the largest UTF8 value, so M\ufff includes all strings that start with M.
            _rangeResolver = new RangePartitionResolver<string>(
                "UserId",
                new Dictionary<Range<string>, string>()
                {
                    { new Range<string>("A", "M\uffff"), _partitionCollection1.SelfLink },
                    { new Range<string>("N", "Z\uffff"), _partitionCollection2.SelfLink },
                });

            _documentDbClient.PartitionResolvers[_documentDatabase.SelfLink] = _rangeResolver;
        }
        /// <summary>
        /// Initialize a RangePartitionResolver.
        /// </summary>
        /// <param name="partitionKeyPropertyName">The property name to be used as the partition Key.</param>
        /// <param name="client">The DocumentDB client instance to use.</param>
        /// <param name="database">The database to run the samples on.</param>
        /// <param name="collectionNames">The names of collections used.</param>
        /// <returns>The created HashPartitionResolver.</returns>
        public static async Task<RangePartitionResolver<string>> InitializeRangeResolver(string partitionKeyPropertyName, DocumentClient client, Database database, string[] collectionNames)
        {
            // Set local to input.
            string[] CollectionNames = collectionNames;
            int numCollectionNames = CollectionNames.Length;

            // Create array of DocumentCollections.
            DocumentCollection[] collections = new DocumentCollection[numCollectionNames];

            // Create string array of Self Links to Collections.
            string[] selfLinks = new string[numCollectionNames];

            //Create some collections to partition data.
            for (int i = 0; i < numCollectionNames; i++)
            {
                collections[i] = await DocumentClientHelper.GetCollectionAsync(client, database, CollectionNames[i]);
                selfLinks[i] = collections[i].SelfLink;
            }

            // Join Self Link Array into a comma separated string.
            string selfLinkString = String.Join(", ", selfLinks);

            // If each collection represents a range, it will have both a start and end point in its range, thus there are 2 rangeNames for each collection.
            string[] rangeNames = new string[numCollectionNames * 2];

            // Keeping track of where in the rangeNames array to add a new start/end of a range.
            int currentRangePosition = 0;

            for (int y = 0; y < numCollectionNames; y++)
            {
                string[] rangeTemp = collectionNames[y].Split('-');
                for (int z = 0; z < rangeTemp.Length; z++)
                {
                    rangeNames[currentRangePosition] = rangeTemp[z];
                    currentRangePosition++;
                }
            }

            // Dictionary needed to input into RangePartitionResolver with corresponding range and collection self link.
            Dictionary<Range<string>, string> rangeCollections = new Dictionary<Range<string>, string>();

            // TO DO:: Iterate through the ranges and add then to rangeCollections with the appropriate start/end point, with the corresponding collection self link.
            //rangeCollections.Add()
            
            RangePartitionResolver<string> rangeResolver = new RangePartitionResolver<string>(
                partitionKeyPropertyName,
                rangeCollections);

            client.PartitionResolvers[database.SelfLink] = rangeResolver;
            return rangeResolver;
        }