Exemple #1
0
        /// <summary>
        /// Create a post trigger that updates metadata: for each inserted doc it will look at doc.size
        /// and update aggregate properties: { minSize, maxSize, totalSize } in the metadata doc.
        /// In the end print to show the aggregate values of min, max, total for all docs.
        /// </summary>
        private static async Task RunPostTrigger(string colSelfLink)
        {
            Random rnd = new Random();

            // 1. Create a trigger.
            string triggerPath = @"js\UpdateMetadata.js";
            string triggerId = Path.GetFileNameWithoutExtension(triggerPath);
            string triggerBody = File.ReadAllText(triggerPath);
            Trigger trigger = new Trigger
            {
                Id = Path.GetFileName(triggerId),
                Body = triggerBody,
                TriggerOperation = TriggerOperation.Create,
                TriggerType = TriggerType.Post
            };

            await TryDeleteStoredProcedure(colSelfLink, trigger.Id);
            await client.CreateTriggerAsync(colSelfLink, trigger);
            
            // 2. Create the metadata document.
            var metaDoc = new 
            {
                    id = "meta", 
                    isMetadata = true, 
                    minSize = 0, 
                    maxSize = 0, 
                    totalSize = 0 
            };

            await client.CreateDocumentAsync(colSelfLink, metaDoc); 
            
            // 3. Import a number of docs with trigger. Use client API this time, we already have sample fot using script.
            var requestOptions = new RequestOptions { PostTriggerInclude = new List<string> { triggerId } };

            await client.CreateDocumentAsync(colSelfLink, new
            {
                size = rnd.Next(1000),
            }, requestOptions);

            await client.CreateDocumentAsync(colSelfLink, new
            {
                size = rnd.Next(1000),
            }, requestOptions);

            await client.CreateDocumentAsync(colSelfLink, new
            {
                size = rnd.Next(1000),
            }, requestOptions);

            await client.CreateDocumentAsync(colSelfLink, new
            {
                size = rnd.Next(1000),
            }, requestOptions);

            await client.CreateDocumentAsync(colSelfLink, new
            {
                size = rnd.Next(1000),
            }, requestOptions);
            
            // 4. Print aggregate info from the metadata document.
            metaDoc = client.CreateDocumentQuery<dynamic>(colSelfLink, "SELECT * FROM root r WHERE r.isMetadata = true").AsEnumerable().First();

            Console.WriteLine("Document statistics: min size: {0}, max size: {1}, total size: {2}", metaDoc.minSize, metaDoc.maxSize, metaDoc.totalSize);
        }
Exemple #2
0
        /// <summary>
        /// Runs a simple script which just does a server side query
        /// </summary>
        private static async Task RunSimpleScript(string colSelfLink)
        {
            // 1. Create stored procedure for script.
            string scriptFileName = @"js\SimpleScript.js";
            string scriptId = Path.GetFileNameWithoutExtension(scriptFileName);
            
            var sproc = new StoredProcedure 
            { 
                Id = scriptId, 
                Body = File.ReadAllText(scriptFileName) 
            };

            await TryDeleteStoredProcedure(colSelfLink, sproc.Id);

            sproc = await client.CreateStoredProcedureAsync(colSelfLink, sproc);

            // 2. Create a document.
            var doc = new
            {
                Name = "Estel",
                Headquarters = "Russia",
                Locations = new [] { new { Country = "Russia", City = "Novosibirsk" } },
                Income = 50000
            };

            Document created = await client.CreateDocumentAsync(colSelfLink, doc);

            // 3. Run the script. Pass "Hello, " as parameter. 
            // The script will take the 1st document and echo: Hello, <document as json>.
            var response = await client.ExecuteStoredProcedureAsync<string>(sproc.SelfLink, "Hello, ");

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

            await client.DeleteDocumentAsync(created.SelfLink);
        }
        private static async Task CreateToDoIndexAsync()
        {
            if (!await ResourceExistsAsync("/indexes/todo"))
            {
                var index = new
                {
                    name = "todo",
                    fields = new[] 
                    { 
                        new { name = "id", type = "Edm.String",               key = true,  facetable = false, filterable = false, searchable = false, sortable = false },
                        new { name = "title", type = "Edm.String",            key = false, facetable = false, filterable = false, searchable = true,  sortable = false },
                        new { name = "description", type = "Edm.String",      key = false, facetable = false, filterable = false, searchable = true,  sortable = false },
                        new { name = "dueDate", type = "Edm.DateTimeOffset",  key = false, facetable = true,  filterable = true,  searchable = false, sortable = true  },
                        new { name = "isComplete", type = "Edm.String",       key = false, facetable = false, filterable = false, searchable = false, sortable = false },
                        new { name = "tags", type = "Collection(Edm.String)", key = false, facetable = true,  filterable = true,  searchable = true,  sortable = false }
                    },
                    suggesters = new[] 
                    { 
                        new { name = "sg", searchMode = "analyzingInfixMatching", sourceFields = new[] { "title", "tags" } }
                    },
                    corsOptions = new
                    {
                        allowedOrigins = new[] { "*" } // use a specific domain when allowing Javascript hit your search index directly, "*" is used for demo purposes
                    }
                };

                await SendAsync(HttpMethod.Post, "/indexes", JsonConvert.SerializeObject(index));
            }
        }
Exemple #4
0
        private static async Task ExcludePathsFromIndex(string databaseLink)
        {
            bool found;
            dynamic dyn = new {
                                id = "doc1",                
                                metaData = "meta",
                                subDoc = new 
                                {
                                    searchable = "searchable",
                                    subSubDoc = new
                                    {
                                        someProperty = "value"
                                    }
                                }
                            };

            //The default behavior is for DocumentDB to index every attribute in every document.
            //There are times when a document contains large amounts of information, in deeply nested structures
            //that you know you will never search on. In extreme cases like this, you can exclude paths from the 
            //index to save on storage cost, improve write performance because there is less work that needs to 
            //happen on writing and also improve read performance because the index is smaller

            var collection = new DocumentCollection
            {
                Id = ConfigurationManager.AppSettings["CollectionId"]
            };

            //special manadatory path of "/" required to denote include entire tree
            collection.IndexingPolicy.IncludedPaths.Add(new IndexingPath {Path = "/" });

            collection.IndexingPolicy.ExcludedPaths.Add("/\"metaData\"/*");
            collection.IndexingPolicy.ExcludedPaths.Add("/\"subDoc\"/\"subSubDoc\"/\"someProperty\"/*");
            collection = await client.CreateDocumentCollectionAsync(databaseLink, collection);

            var created = await client.CreateDocumentAsync(collection.SelfLink, dyn);

            //Querying for a document on either metaData or /subDoc/subSubDoc/someProperty > fail because they were excluded
            try
            {
                client.CreateDocumentQuery(collection.SelfLink, String.Format("SELECT * FROM root r WHERE r.metaData='{0}'",
                    "meta")).AsEnumerable().Any();
            }
            catch (Exception e)
            {
                var baseEx = (DocumentClientException) e.GetBaseException();
                if (baseEx.StatusCode != HttpStatusCode.BadRequest) { throw; }
            }

            try
            {
                found = client.CreateDocumentQuery(collection.SelfLink, String.Format("SELECT * FROM root r WHERE r.subDoc.subSubDoc.someProperty='{0}'", 
                    "value")).AsEnumerable().Any();
            }
            catch (Exception e)
            {
                var baseEx = (DocumentClientException)e.GetBaseException();
                if (baseEx.StatusCode != HttpStatusCode.BadRequest) { throw; }
            }

            //Querying for a document using id, or even subDoc/searchable > succeed because they were not excluded
            found = client.CreateDocumentQuery(collection.SelfLink, String.Format("SELECT * FROM root r WHERE r.id='{0}'", "doc1")).AsEnumerable().Any();
            
            if (!found) throw new ApplicationException("Should've found the document");

            found = client.CreateDocumentQuery(collection.SelfLink, String.Format("SELECT * FROM root r WHERE r.subDoc.searchable='{0}'", 
                "searchable")).AsEnumerable().Any();

            if (!found) throw new ApplicationException("Should've found the document");

            //Cleanup collection
            await client.DeleteDocumentCollectionAsync(collection.SelfLink);
            
            //To exclude subDoc and anything under it add an ExcludePath of "/\"subDoc\"/*"
            collection = new DocumentCollection
            {
                Id = ConfigurationManager.AppSettings["CollectionId"]
            };

            //special manadatory path of "/" required to denote include entire tree
            collection.IndexingPolicy.IncludedPaths.Add(new IndexingPath { Path = "/" });

            collection.IndexingPolicy.ExcludedPaths.Add("/\"subDoc\"/*");
            collection = await client.CreateDocumentCollectionAsync(databaseLink, collection);

            //Query for /subDoc/searchable > fail because we have excluded the whole subDoc, and all its children.
            try
            {
                client.CreateDocumentQuery(collection.SelfLink, String.Format("SELECT * FROM root r WHERE r.subDoc.searchable='{0}'",
                    "searchable")).AsEnumerable().Any();
            }
            catch (Exception e)
            {
                var baseEx = (DocumentClientException)e.GetBaseException();
                if (baseEx.StatusCode != HttpStatusCode.BadRequest) { throw; }
            }
            
            //Cleanup
            await client.DeleteDocumentCollectionAsync(collection.SelfLink);
        }
        private static async Task CreateDocumentDBIndexerAsync()
        {
            string account = new Uri(ConfigurationManager.AppSettings["docdb-endpoint"]).Host.Split('.')[0];
            string authKey = ConfigurationManager.AppSettings["docdb-authKey"];
            string database = ConfigurationManager.AppSettings["docdb-database"];
            string collection = ConfigurationManager.AppSettings["docdb-collection"];

            // create data source
            if (!await ResourceExistsAsync("/datasources/tododocdb"))
            {
                var dataSource = new
                {
                    name = "tododocdb",
                    type = "documentdb",
                    credentials = new
                    {
                        connectionString = String.Format("AccountName={0};AuthKey={1};DatabaseId={2}", account, authKey, database)
                    },
                    container = new
                    {
                        name = collection
                    },
                    dataChangeDetectionPolicy = new Dictionary<string, object>
                    {
                        { "@odata.type", "#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy" },
                        { "highWaterMarkColumnName", "_ts" }, // DocumentDB has a built-in timestamp property called "_ts"
                    }
                };

                await SendAsync(HttpMethod.Post, "/datasources", JsonConvert.SerializeObject(dataSource));
            }

            // create indexer and schedule it
            if (!await ResourceExistsAsync("/indexers/todoixr"))
            {
                var indexer = new
                {
                    name = "todoixr",
                    dataSourceName = "tododocdb",
                    schedule = new { interval = "PT5M" }, // every 5 minutes
                    targetIndexName = "todo"
                };

                await SendAsync(HttpMethod.Post, "/indexers", JsonConvert.SerializeObject(indexer));
            }
        }