Exemplo n.º 1
0
        /// <summary>
        /// Runs a simple script which just does a server side query
        /// </summary>
        private static async Task RunSimpleScript(CosmosContainer container)
        {
            // 1. Create stored procedure for script.
            string scriptFileName = @"js\SimpleScript.js";
            string scriptId       = Path.GetFileNameWithoutExtension(scriptFileName);

            await TryDeleteStoredProcedure(container, scriptId);

            CosmosScripts           cosmosScripts = container.GetScripts();
            StoredProcedureResponse sproc         = await cosmosScripts.CreateStoredProcedureAsync(new CosmosStoredProcedureSettings(scriptId, File.ReadAllText(scriptFileName)));

            // 2. Create a document.
            SampleDocument doc = new SampleDocument
            {
                Id           = Guid.NewGuid().ToString(),
                LastName     = "Estel",
                Headquarters = "Russia",
                Locations    = new Location[] { new Location {
                                                    Country = "Russia", City = "Novosibirsk"
                                                } },
                Income = 50000
            };

            ItemResponse <SampleDocument> created = await container.CreateItemAsync(doc, new PartitionKey(doc.LastName));

            // 3. Run the script. Pass "Hello, " as parameter.
            // The script will take the 1st document and echo: Hello, <document as json>.
            StoredProcedureExecuteResponse <string> response = await container.GetScripts().ExecuteStoredProcedureAsync <string, string>(new PartitionKey(doc.LastName), scriptId, "Hello");

            Console.WriteLine("Result from script: {0}\r\n", response.Resource);

            await container.DeleteItemAsync <SampleDocument>(new PartitionKey(doc.LastName), doc.Id);
        }
        public async Task TestReducePageSizeScenario()
        {
            int partitionKey = 0;
            // Create some docs to make sure that one separate response is returned for 1st execute of query before retries.
            // These are to make sure continuation token is passed along during retries.
            string sprocId   = "createTwoDocs";
            string sprocBody = @"function(startIndex) { for (var i = 0; i < 2; ++i) __.createDocument(
                            __.getSelfLink(),
                            { id: 'doc' + (i + startIndex).toString(), value: 'y'.repeat(1500000), pk:0 },
                            err => { if (err) throw err;}
                        );}";

            CosmosScripts scripts = this.Container.GetScripts();

            StoredProcedureResponse storedProcedureResponse =
                await scripts.CreateStoredProcedureAsync(new CosmosStoredProcedureSettings(sprocId, sprocBody));

            ManualResetEvent allDocsProcessed = new ManualResetEvent(false);

            int    processedDocCount      = 0;
            string accumulator            = string.Empty;
            ChangeFeedProcessor processor = this.Container
                                            .CreateChangeFeedProcessorBuilder("test", (IReadOnlyCollection <dynamic> docs, CancellationToken token) =>
            {
                processedDocCount += docs.Count();
                foreach (var doc in docs)
                {
                    accumulator += doc.id.ToString() + ".";
                }
                if (processedDocCount == 5)
                {
                    allDocsProcessed.Set();
                }

                return(Task.CompletedTask);
            })
                                            .WithStartFromBeginning()
                                            .WithInstanceName("random")
                                            .WithMaxItems(6)
                                            .WithLeaseContainer(this.LeaseContainer).Build();

            // Generate the payload
            await scripts.ExecuteStoredProcedureAsync <int, object>(new PartitionKey(partitionKey), sprocId, 0);

            // Create 3 docs each 1.5MB. All 3 do not fit into MAX_RESPONSE_SIZE (4 MB). 2nd and 3rd are in same transaction.
            var content = string.Format("{{\"id\": \"doc2\", \"value\": \"{0}\", \"pk\": 0}}", new string('x', 1500000));

            await this.Container.CreateItemAsync(JsonConvert.DeserializeObject <dynamic>(content), new PartitionKey(partitionKey));

            await scripts.ExecuteStoredProcedureAsync <int, object>(new PartitionKey(partitionKey), sprocId, 3);

            await processor.StartAsync();

            // Letting processor initialize and pickup changes
            var isStartOk = allDocsProcessed.WaitOne(10 * BaseChangeFeedClientHelper.ChangeFeedSetupTime);
            await processor.StopAsync();

            Assert.IsTrue(isStartOk, "Timed out waiting for docs to process");
            Assert.AreEqual("doc0.doc1.doc2.doc3.doc4.", accumulator);
        }
Exemplo n.º 3
0
        /// <summary>
        /// If a Stored Procedure is found on the DocumentCollection for the Id supplied it is deleted
        /// </summary>
        /// <param name="collectionLink">DocumentCollection to search for the Stored Procedure</param>
        /// <param name="sprocId">Id of the Stored Procedure to delete</param>
        /// <returns></returns>
        private static async Task TryDeleteStoredProcedure(CosmosContainer container, string sprocId)
        {
            CosmosScripts           cosmosScripts = container.GetScripts();
            StoredProcedureResponse sproc         = await cosmosScripts.ReadStoredProcedureAsync(sprocId);

            if (sproc != null)
            {
                await cosmosScripts.DeleteStoredProcedureAsync(sprocId);
            }
        }
        public async Task TestInitialize()
        {
            await base.TestInit();

            string            containerName           = Guid.NewGuid().ToString();
            ContainerResponse cosmosContainerResponse = await this.database
                                                        .CreateContainerIfNotExistsAsync(containerName, "/user");

            this.container = cosmosContainerResponse;
            this.scripts   = this.container.GetScripts();
        }
        public async Task TestInitialize()
        {
            await base.TestInit();

            string            PartitionKey = "/status";
            ContainerResponse response     = await this.database.Containers.CreateContainerAsync(
                new CosmosContainerSettings(id : Guid.NewGuid().ToString(), partitionKeyPath : PartitionKey),
                cancellationToken : this.cancellationToken);

            Assert.IsNotNull(response);
            Assert.IsNotNull(response.Container);
            Assert.IsNotNull(response.Resource);
            this.container = (CosmosContainerCore)response;
            this.scripts   = this.container.GetScripts();
        }
Exemplo n.º 6
0
        /// <summary>
        /// Get documents ordered by some doc property. This is done using OrderBy stored procedure.
        /// </summary>
        private static async Task RunOrderBy(CosmosContainer container)
        {
            // 1. Create or get the stored procedure.
            string body     = File.ReadAllText(@"js\OrderBy.js");
            string scriptId = "OrderBy";

            await TryDeleteStoredProcedure(container, scriptId);

            CosmosScripts           cosmosScripts = container.GetScripts();
            StoredProcedureResponse sproc         = await cosmosScripts.CreateStoredProcedureAsync(new CosmosStoredProcedureSettings(scriptId, body));

            // 2. Prepare to run stored procedure.
            string orderByFieldName = "FamilyId";
            string filterQuery      = string.Format(CultureInfo.InvariantCulture, "SELECT r.FamilyId FROM root r WHERE r.{0} > 10", orderByFieldName);
            // Note: in order to do a range query (> 10) on this field, the collection must have a range index set for this path (see ReadOrCreateCollection).

            int?continuationToken = null;
            int batchCount        = 0;

            do
            {
                // 3. Run the stored procedure.
                StoredProcedureExecuteResponse <OrderByResult> response = await cosmosScripts.ExecuteStoredProcedureAsync <object, OrderByResult>(
                    new PartitionKey("Andersen"),
                    scriptId,
                    new { filterQuery, orderByFieldName, continuationToken });

                // 4. Process stored procedure response.
                continuationToken = response.Resource.Continuation;

                Console.WriteLine("Printing documents filtered/ordered by '{0}' and ordered by '{1}', batch #{2}:", filterQuery, orderByFieldName, batchCount++);
                foreach (dynamic doc in response.Resource.Result)
                {
                    Console.WriteLine(doc.ToString());
                }
            } while (continuationToken != null);
            // 5. To take care of big response, loop until Response.continuation token is null (see OrderBy.js for details).
        }
Exemplo n.º 7
0
        /// <summary>
        /// Import many documents using stored procedure.
        /// </summary>
        private static async Task RunBulkImport(CosmosContainer container)
        {
            string inputDirectory = @".\Data\";
            string inputFileMask  = "*.json";
            int    maxFiles       = 2000;
            int    maxScriptSize  = 50000;

            // 1. Get the files.
            string[]      fileNames = Directory.GetFiles(inputDirectory, inputFileMask);
            DirectoryInfo di        = new DirectoryInfo(inputDirectory);

            FileInfo[] fileInfos = di.GetFiles(inputFileMask);

            // 2. Prepare for import.
            int currentCount = 0;
            int fileCount    = maxFiles != 0 ? Math.Min(maxFiles, fileNames.Length) : fileNames.Length;

            // 3. Create stored procedure for this script.
            string scriptId = "BulkImport";
            string body     = File.ReadAllText(@".\JS\BulkImport.js");

            await TryDeleteStoredProcedure(container, scriptId);

            CosmosScripts           cosmosScripts = container.GetScripts();
            StoredProcedureResponse sproc         = await cosmosScripts.CreateStoredProcedureAsync(new CosmosStoredProcedureSettings(scriptId, body));

            // 4. Create a batch of docs (MAX is limited by request size (2M) and to script for execution.
            // We send batches of documents to create to script.
            // Each batch size is determined by MaxScriptSize.
            // MaxScriptSize should be so that:
            // -- it fits into one request (MAX request size is 16Kb).
            // -- it doesn't cause the script to time out.
            // -- it is possible to experiment with MaxScriptSize to get best performance given number of throttles, etc.
            while (currentCount < fileCount)
            {
                // 5. Create args for current batch.
                //    Note that we could send a string with serialized JSON and JSON.parse it on the script side,
                //    but that would cause script to run longer. Since script has timeout, unload the script as much
                //    as we can and do the parsing by client and framework. The script will get JavaScript objects.
                string    argsJson = CreateBulkInsertScriptArguments(fileNames, currentCount, fileCount, maxScriptSize);
                dynamic[] args     = new dynamic[] { JsonConvert.DeserializeObject <dynamic>(argsJson) };

                // 6. execute the batch.
                StoredProcedureExecuteResponse <int> scriptResult = await cosmosScripts.ExecuteStoredProcedureAsync <dynamic, int>(new PartitionKey("Andersen"), scriptId, args);

                // 7. Prepare for next batch.
                int currentlyInserted = scriptResult.Resource;
                currentCount += currentlyInserted;
            }

            // 8. Validate
            int numDocs = 0;

            FeedIterator <dynamic> setIterator = container.GetItemsIterator <dynamic>();

            while (setIterator.HasMoreResults)
            {
                FeedResponse <dynamic> response = await setIterator.FetchNextSetAsync();

                numDocs += response.Count();
            }

            Console.WriteLine("Found {0} documents in the collection. There were originally {1} files in the Data directory\r\n", numDocs, fileCount);
        }