/// <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); }
/// <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); } }
/// <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). }
/// <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); }