예제 #1
0
        public void CheckSearchParameter(
            string resourceType,
            IEnumerable <SearchParameterInfo> parameters)
        {
            SearchParameterToTypeResolver.Log = s => _outputHelper.WriteLine(s);

            foreach (var parameterInfo in parameters)
            {
                var fhirPath        = parameterInfo.Expression;
                var parameterName   = parameterInfo.Name;
                var searchParamType = parameterInfo.Type;

                _outputHelper.WriteLine("** Evaluating: " + fhirPath);

                var converters =
                    GetConvertsForSearchParameters(resourceType, parameterInfo);

                Assert.True(
                    converters.Any(x => x.hasConverter),
                    $"{parameterName} ({resourceType}) was not able to be mapped.");

                string listedTypes = string.Join(",", converters.Select(x => x.result.ClassMapping.NativeType.Name));
                _outputHelper.WriteLine($"Info: {parameterName} ({searchParamType}) found {listedTypes} types ({converters.Count}).");

                foreach (var result in converters.Where(x => x.hasConverter || !parameterInfo.IsPartiallySupported))
                {
                    var found = SearchParameterFixtureData.Manager.TryGetConverter(result.result.ClassMapping.NativeType, SearchIndexer.GetSearchValueTypeForSearchParamType(result.result.SearchParamType), out var converter);

                    var    converterText     = found ? converter.GetType().Name : "None";
                    string searchTermMapping = $"Search term '{parameterName}' ({result.result.SearchParamType}) mapped to '{result.result.ClassMapping.NativeType.Name}', converter: {converterText}";
                    _outputHelper.WriteLine(searchTermMapping);

                    Assert.True(found, searchTermMapping);
                }
            }
        }
예제 #2
0
        public async Task <Response <SearchIndexer> > CreateOrUpdateAsync(string indexerName, SearchIndexer indexer, string ifMatch = null, string ifNoneMatch = null, CancellationToken cancellationToken = default)
        {
            if (indexerName == null)
            {
                throw new ArgumentNullException(nameof(indexerName));
            }
            if (indexer == null)
            {
                throw new ArgumentNullException(nameof(indexer));
            }

            using var message = CreateCreateOrUpdateRequest(indexerName, indexer, ifMatch, ifNoneMatch);
            await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false);

            switch (message.Response.Status)
            {
            case 200:
            case 201:
            {
                SearchIndexer value = default;
                using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false);

                value = SearchIndexer.DeserializeSearchIndexer(document.RootElement);
                return(Response.FromValue(value, message.Response));
            }
        public async ValueTask <Response <SearchIndexer> > CreateOrUpdateAsync(string indexerName, SearchIndexer indexer, Guid?xMsClientRequestId = null, string ifMatch = null, string ifNoneMatch = null, CancellationToken cancellationToken = default)
        {
            if (indexerName == null)
            {
                throw new ArgumentNullException(nameof(indexerName));
            }
            if (indexer == null)
            {
                throw new ArgumentNullException(nameof(indexer));
            }

            using var scope = _clientDiagnostics.CreateScope("IndexersClient.CreateOrUpdate");
            scope.Start();
            try
            {
                using var message = CreateCreateOrUpdateRequest(indexerName, indexer, xMsClientRequestId, ifMatch, ifNoneMatch);
                await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false);

                switch (message.Response.Status)
                {
                case 200:
                case 201:
                {
                    SearchIndexer value = default;
                    using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false);

                    if (document.RootElement.ValueKind == JsonValueKind.Null)
                    {
                        value = null;
                    }
                    else
                    {
                        value = SearchIndexer.DeserializeSearchIndexer(document.RootElement);
                    }
                    return(Response.FromValue(value, message.Response));
                }
        public async Task CreateDoubleEncryptedIndex()
        {
            string keyVaultUrl = TestEnvironment.KeyVaultUrl;

            if (string.IsNullOrEmpty(keyVaultUrl))
            {
                Assert.Ignore("A Key Vault was not deployed");
            }

            // Create the key and persist the name and version.
            KeyVaultKey key = await CreateEncryptionKey(keyVaultUrl);

            Environment.SetEnvironmentVariable("KEYVAULT_URL", keyVaultUrl);
            Environment.SetEnvironmentVariable("KEYVAULT_KEY_NAME", key.Name);
            Environment.SetEnvironmentVariable("KEYVAULT_KEY_VERSION", key.Properties.Version);

            // Persist the service principal.
            Environment.SetEnvironmentVariable("APPLICATION_ID", TestEnvironment.ClientId);
            Environment.SetEnvironmentVariable("APPLICATION_SECRET", TestEnvironment.RecordedClientSecret);

            // Create the blob container and persist connection information.
            await using SearchResources resources = await SearchResources.CreateWithBlobStorageAndIndexAsync(this, populate : true);

            Environment.SetEnvironmentVariable("STORAGE_CONNECTION_STRING", resources.StorageAccountConnectionString);
            Environment.SetEnvironmentVariable("STORAGE_CONTAINER_NAME", resources.BlobContainerName);
            Environment.SetEnvironmentVariable("SEARCH_ENDPOINT", resources.Endpoint.ToString());
            Environment.SetEnvironmentVariable("SEARCH_API_KEY", resources.PrimaryApiKey);

            // Define clean up tasks to be invoked in reverse order added.
            Stack <Func <Task> > cleanUpTasks = new Stack <Func <Task> >();

            try
            {
                #region Snippet:Azure_Search_Tests_Sample06_EncryptedIndex_CreateDoubleEncryptedIndex_Index
                // Create a credential to connect to Key Vault and use a specific key version created previously.
                SearchResourceEncryptionKey encryptionKey = new SearchResourceEncryptionKey(
                    new Uri(Environment.GetEnvironmentVariable("KEYVAULT_URL")),
                    Environment.GetEnvironmentVariable("KEYVAULT_KEY_NAME"),
                    Environment.GetEnvironmentVariable("KEYVAULT_KEY_VERSION"))
                {
                    ApplicationId     = Environment.GetEnvironmentVariable("APPLICATION_ID"),
                    ApplicationSecret = Environment.GetEnvironmentVariable("APPLICATION_SECRET"),
                };

                // Create a connection to our storage blob container using the credential.
                string dataSourceConnectionName = "hotels-data-source";
                /*@@*/ dataSourceConnectionName = Recording.Random.GetName();
                SearchIndexerDataSourceConnection dataSourceConnection = new SearchIndexerDataSourceConnection(
                    dataSourceConnectionName,
                    SearchIndexerDataSourceType.AzureBlob,
                    Environment.GetEnvironmentVariable("STORAGE_CONNECTION_STRING"),
                    new SearchIndexerDataContainer(
                        Environment.GetEnvironmentVariable("STORAGE_CONTAINER_NAME")
                        )
                    )
                {
                    EncryptionKey = encryptionKey
                };

                // Create an indexer to process documents from the blob container into the index.
                // You can optionally configure a skillset to use cognitive services when processing documents.
                // Set the SearchIndexerSkillset.EncryptionKey to the same credential if you use a skillset.
                string indexName = "hotels";
                /*@@*/ indexName = resources.IndexName;
                string indexerName = "hotels-indexer";
                /*@@*/ indexerName = Recording.Random.GetName();
                SearchIndexer indexer = new SearchIndexer(
                    indexerName,
                    dataSourceConnectionName,
                    indexName)
                {
                    EncryptionKey = encryptionKey,

                    // Map the fields in our documents we want to index.
                    FieldMappings =
                    {
                        new FieldMapping("hotelId"),
                        new FieldMapping("hotelName"),
                        new FieldMapping("description"),
                        new FieldMapping("tags"),
                        new FieldMapping("address")
                    },
                    Parameters = new IndexingParameters
                    {
                        // Tell the indexer to parse each blob as a separate JSON document.
                        IndexingParametersConfiguration = new IndexingParametersConfiguration
                        {
                            ParsingMode = BlobIndexerParsingMode.Json
                        }
                    }
                };

                // Now connect to our Search service and set up the data source and indexer.
                // Documents already in the storage blob will begin indexing immediately.
                Uri endpoint = new Uri(Environment.GetEnvironmentVariable("SEARCH_ENDPOINT"));
                AzureKeyCredential credential = new AzureKeyCredential(
                    Environment.GetEnvironmentVariable("SEARCH_API_KEY"));

                SearchIndexerClient indexerClient = new SearchIndexerClient(endpoint, credential);
                /*@@*/ indexerClient = resources.GetIndexerClient();
                indexerClient.CreateDataSourceConnection(dataSourceConnection);
                /*@@*/ cleanUpTasks.Push(() => indexerClient.DeleteDataSourceConnectionAsync(dataSourceConnectionName));
                indexerClient.CreateIndexer(indexer);
                /*@@*/ cleanUpTasks.Push(() => indexerClient.DeleteIndexerAsync(indexerName));
                #endregion Snippet:Azure_Search_Tests_Sample06_EncryptedIndex_CreateDoubleEncryptedIndex_Index

                await WaitForIndexingAsync(indexerClient, indexerName);

                #region Snippet:Azure_Search_Tests_Sample06_EncryptedIndex_CreateDoubleEncryptedIndex_Query
                // Create a SearchClient and search for luxury hotels. In production, be sure to use the query key.
                SearchClient searchClient = new SearchClient(endpoint, "hotels", credential);
                /*@@*/ searchClient = resources.GetSearchClient();
                /*@@*/ bool found = false;
                Response <SearchResults <Hotel> > results = searchClient.Search <Hotel>("luxury hotels");
                foreach (SearchResult <Hotel> result in results.Value.GetResults())
                {
                    Hotel hotel = result.Document;
                    /*@@*/ found = true;

                    Console.WriteLine($"{hotel.HotelName} ({hotel.HotelId})");
                    Console.WriteLine($"  Description: {hotel.Description}");
                }
                #endregion Snippet:Azure_Search_Tests_Sample06_EncryptedIndex_CreateDoubleEncryptedIndex_Query

                Assert.IsTrue(found, "No luxury hotels were found in index");
            }
            finally
            {
                // We want to await these individual to create a deterministic order for playing back tests.
                foreach (Func <Task> cleanUpTask in cleanUpTasks)
                {
                    await cleanUpTask();
                }
            }
        }
        public void CreateDataSource()
        {
            //creating index
            SearchIndexClient   indexClient   = new SearchIndexClient(Uri, keyCredential);
            SearchIndexerClient indexerClient = new SearchIndexerClient(Uri, keyCredential);

            Console.WriteLine("Creating index...");
            FieldBuilder fieldBuilder = new FieldBuilder();
            var          searchFields = fieldBuilder.Build(typeof(InteractionDetails));
            var          searchIndex  = new SearchIndex("interaction-sql-idx", searchFields);

            // If we have run the sample before, this index will be populated
            // We can clear the index by deleting it if it exists and creating
            // it again
            CleanupSearchIndexClientResources(indexClient, searchIndex);

            indexClient.CreateOrUpdateIndexAsync(searchIndex);
            //Creating data source

            Console.WriteLine("Creating data source...");

            var dataSource =
                new SearchIndexerDataSourceConnection(
                    "interaction-sql-ds",
                    SearchIndexerDataSourceType.AzureSql,
                    azureSQLConnectionStr,
                    new SearchIndexerDataContainer("[Interaction]"));

            indexerClient.CreateOrUpdateDataSourceConnection(dataSource);

            //Creating indexer
            Console.WriteLine("Creating Azure SQL indexer...");

            //var schedule = new IndexingSchedule(TimeSpan.FromDays(1))
            //{
            //    StartTime = DateTimeOffset.Now
            //};

            var parameters = new IndexingParameters()
            {
                BatchSize              = 100,
                MaxFailedItems         = 0,
                MaxFailedItemsPerBatch = 0
            };



            // Indexer declarations require a data source and search index.
            // Common optional properties include a schedule, parameters, and field mappings
            // The field mappings below are redundant due to how the Hotel class is defined, but
            // we included them anyway to show the syntax
            var indexer = new SearchIndexer("interaction-sql-idxr", dataSource.Name, searchIndex.Name)
            {
                Description = "Data indexer",
                Schedule    = new IndexingSchedule(TimeSpan.FromMinutes(5)),
                Parameters  = parameters,
            };

            indexerClient.CreateOrUpdateIndexerAsync(indexer);

            Console.WriteLine("Running Azure SQL indexer...");

            try
            {
                indexerClient.RunIndexerAsync(indexer.Name);
            }
            catch (CloudException e) when(e.Response.StatusCode == (HttpStatusCode)429)
            {
                Console.WriteLine("Failed to run indexer: {0}", e.Response.Content);
            }

            // Wait 5 seconds for indexing to complete before checking status
            Console.WriteLine("Waiting for indexing...\n");
            System.Threading.Thread.Sleep(5000);
        }
예제 #6
0
            private static void SearchAssets(SearchContext context, List <SearchItem> items, SearchProvider provider, SearchIndexer fileIndexer)
            {
                var filter         = context.searchQuery;
                var searchPackages = context.categories.Any(c => c.name.id == "packages" && c.isEnabled);
                var searchGuids    = context.categories.Any(c => c.name.id == "guid" && c.isEnabled);

                if (searchGuids)
                {
                    var gui2Path = AssetDatabase.GUIDToAssetPath(filter);
                    if (!System.String.IsNullOrEmpty(gui2Path))
                    {
                        items.Add(provider.CreateItem(gui2Path, -1, $"{Path.GetFileName(gui2Path)} ({filter})", null, null, null));
                    }
                }

                if (fileIndexer.IsReady())
                {
                    if (filter.IndexOfAny(k_InvalidIndexedChars) == -1)
                    {
                        items.AddRange(fileIndexer.Search(filter, searchPackages ? int.MaxValue : 100).Take(201)
                                       .Select(e =>
                        {
                            var filename      = Path.GetFileName(e.path);
                            var filenameNoExt = Path.GetFileNameWithoutExtension(e.path);
                            var itemScore     = e.score;
                            if (filenameNoExt.Equals(filter, StringComparison.InvariantCultureIgnoreCase))
                            {
                                itemScore = SearchProvider.k_RecentUserScore + 1;
                            }
                            return(provider.CreateItem(e.path, itemScore, filename, null, null, null));
                        }));
                        if (!context.wantsMore)
                        {
                            return;
                        }
                    }
                }

                if (!searchPackages)
                {
                    if (!filter.Contains("a:assets"))
                    {
                        filter = "a:assets " + filter;
                    }
                }

                items.AddRange(AssetDatabase.FindAssets(filter)
                               .Select(AssetDatabase.GUIDToAssetPath)
                               .Take(202)
                               .Select(path => provider.CreateItem(path, Path.GetFileName(path))));

                if (context.searchQuery.Contains('*'))
                {
                    var safeFilter = string.Join("_", context.searchQuery.Split(k_InvalidSearchFileChars));
                    items.AddRange(Directory.EnumerateFiles(Application.dataPath, safeFilter, SearchOption.AllDirectories)
                                   .Select(path => provider.CreateItem(path.Replace(Application.dataPath, "Assets").Replace("\\", "/"),
                                                                       Path.GetFileName(path))));
                }
            }
예제 #7
0
    private static void RunThreadIndexing()
    {
        var sw = new System.Diagnostics.Stopwatch();

        sw.Start();

        index = new SearchIndexer();
        index.Start();
        int completed  = 0;
        var metaFiles  = Directory.GetFiles("Assets", "*.meta", SearchOption.AllDirectories);
        var progressId = Progress.Start($"Scanning dependencies ({metaFiles.Length} assets)");

        Parallel.ForEach(metaFiles, mf =>
        {
            Progress.Report(progressId, completed / (float)metaFiles.Length, mf);
            var assetPath = mf.Replace("\\", "/").Substring(0, mf.Length - 5).ToLowerInvariant();
            if (!File.Exists(assetPath))
            {
                return;
            }

            var guid = ToGuid(assetPath);
            Progress.Report(progressId, completed / (float)metaFiles.Length, assetPath);

            TrackGuid(guid);
            pathToGuidMap.TryAdd(assetPath, guid);
            guidToPathMap.TryAdd(guid, assetPath);

            var mfc = File.ReadAllText(mf);
            ScanDependencies(guid, mfc);

            using (var file = new StreamReader(assetPath))
            {
                var header = new char[5];
                if (file.ReadBlock(header, 0, header.Length) == header.Length &&
                    header[0] == '%' && header[1] == 'Y' && header[2] == 'A' && header[3] == 'M' && header[4] == 'L')
                {
                    var ac = file.ReadToEnd();
                    ScanDependencies(guid, ac);
                }
            }

            Progress.Report(progressId, ++completed / (float)metaFiles.Length);
        });
        Progress.Finish(progressId, Progress.Status.Succeeded);

        completed = 0;
        var total = pathToGuidMap.Count + guidToRefsMap.Count + guidFromRefsMap.Count;

        progressId = Progress.Start($"Indexing {total} dependencies");
        foreach (var kvp in pathToGuidMap)
        {
            var guid = kvp.Value;
            var path = kvp.Key;

            var ext = Path.GetExtension(path);
            if (ext.Length > 0 && ext[0] == '.')
            {
                ext = ext.Substring(1);
            }

            Progress.Report(progressId, completed++ / (float)total, path);

            var di = AddGuid(guid);

            index.AddExactWord("all", 0, di);
            AddStaticProperty("id", guid, di, exact: true);
            AddStaticProperty("path", path, di, exact: true);
            AddStaticProperty("t", GetExtension(path).ToLowerInvariant(), di);
            index.AddWord(guid, guid.Length, 0, di);
            IndexWordComponents(di, path);
        }

        foreach (var kvp in guidToRefsMap)
        {
            var guid = kvp.Key;
            var refs = kvp.Value.Keys;
            var di   = AddGuid(guid);
            index.AddWord(guid, guid.Length, 0, di);

            Progress.Report(progressId, completed++ / (float)total, guid);

            index.AddNumber("out", refs.Count, 0, di);
            foreach (var r in refs)
            {
                AddStaticProperty("to", r, di);
            }
        }

        foreach (var kvp in guidFromRefsMap)
        {
            var guid = kvp.Key;
            var refs = kvp.Value.Keys;
            var di   = AddGuid(guid);

            Progress.Report(progressId, completed++ / (float)total, guid);

            index.AddNumber("in", refs.Count, 0, di);
            foreach (var r in refs)
            {
                AddStaticProperty("from", r, di);
            }

            if (guidToPathMap.TryGetValue(guid, out var path))
            {
                AddStaticProperty("is", "valid", di);
            }
            else
            {
                AddStaticProperty("is", "missing", di);

                foreach (var r in refs)
                {
                    var refDocumentIndex = AddGuid(r);
                    AddStaticProperty("is", "broken", refDocumentIndex);
                    var refDoc = index.GetDocument(refDocumentIndex);
                    if (refDoc.metadata == null)
                    {
                        refDoc.metadata = $"Broken links {guid}";
                    }
                    else
                    {
                        refDoc.metadata += $", {guid}";
                    }
                }

                var refString = string.Join(", ", refs.Select(r =>
                {
                    if (guidToPathMap.TryGetValue(r, out var rp))
                    {
                        return(rp);
                    }
                    return(r);
                }));
                index.GetDocument(di).metadata = $"Refered by {refString}";
            }
        }

        Progress.SetDescription(progressId, $"Saving dependency index at {dependencyIndexLibraryPath}");

        index.Finish((bytes) =>
        {
            File.WriteAllBytes(dependencyIndexLibraryPath, bytes);
            Progress.Finish(progressId, Progress.Status.Succeeded);

            Debug.Log($"Dependency indexing took {sw.Elapsed.TotalMilliseconds,3:0.##} ms " +
                      $"and was saved at {dependencyIndexLibraryPath} ({EditorUtility.FormatBytes(bytes.Length)} bytes)");
        }, removedDocuments: null);
    }
        public async Task CreateIndexerAsync()
        {
            await using SearchResources resources = await SearchResources.CreateWithBlobStorageAsync(this, populate : true);

            Environment.SetEnvironmentVariable("SEARCH_ENDPOINT", resources.Endpoint.ToString());
            Environment.SetEnvironmentVariable("SEARCH_API_KEY", resources.PrimaryApiKey);
            Environment.SetEnvironmentVariable("STORAGE_CONNECTION_STRING", resources.StorageAccountConnectionString);
            Environment.SetEnvironmentVariable("STORAGE_CONTAINER", resources.BlobContainerName);
            Environment.SetEnvironmentVariable("COGNITIVE_SERVICES_KEY", resources.CognitiveServicesKey);

            // Define clean up tasks to be invoked in reverse order added.
            Stack <Func <Task> > cleanUpTasks = new Stack <Func <Task> >();

            try
            {
                #region Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_CreateSynonymMap
                // Create a new SearchIndexClient
                Uri endpoint = new Uri(Environment.GetEnvironmentVariable("SEARCH_ENDPOINT"));
                AzureKeyCredential credential = new AzureKeyCredential(
                    Environment.GetEnvironmentVariable("SEARCH_API_KEY"));
                SearchIndexClient indexClient = new SearchIndexClient(endpoint, credential);
#if !SNIPPET
                indexClient = resources.GetIndexClient();
#endif

                // Create a synonym map from a file containing country names and abbreviations
                // using the Solr format with entry on a new line using \n, for example:
                // United States of America,US,USA\n
                string synonymMapName = "countries";
#if !SNIPPET
                synonymMapName = Recording.Random.GetName();
#endif
                string synonymMapPath = "countries.txt";
#if !SNIPPET
                synonymMapPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "Samples", "countries.txt");
#endif

                SynonymMap synonyms;
#if SNIPPET
                using (StreamReader file = File.OpenText(synonymMapPath))
                {
                    synonyms = new SynonymMap(synonymMapName, file);
                }
#else
                synonyms = new SynonymMap(synonymMapName, CountriesSolrSynonymMap);
#endif

                await indexClient.CreateSynonymMapAsync(synonyms);

                #endregion Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_CreateSynonymMap

                // Make sure our synonym map gets deleted, which is not deleted when our
                // index is deleted when our SearchResources goes out of scope.
                cleanUpTasks.Push(() => indexClient.DeleteSynonymMapAsync(synonymMapName));

                #region Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_CreateIndex
                // Create the index
                string indexName = "hotels";
#if !SNIPPET
                indexName = Recording.Random.GetName();
#endif
                SearchIndex index = new SearchIndex(indexName)
                {
                    Fields =
                    {
                        new SimpleField("hotelId",                    SearchFieldDataType.String)
                        {
                            IsKey = true,                             IsFilterable = true, IsSortable  = true
                        },
                        new SearchableField("hotelName")
                        {
                            IsFilterable = true,                      IsSortable   = true
                        },
                        new SearchableField("description")
                        {
                            AnalyzerName = LexicalAnalyzerName.EnLucene
                        },
                        new SearchableField("descriptionFr")
                        {
                            AnalyzerName = LexicalAnalyzerName.FrLucene
                        },
                        new SearchableField("tags",                   collection: true)
                        {
                            IsFilterable = true,                      IsFacetable  = true
                        },
                        new ComplexField("address")
                        {
                            Fields =
                            {
                                new SearchableField("streetAddress"),
                                new SearchableField("city")
                                {
                                    IsFilterable = true,             IsSortable                 = true, IsFacetable = true
                                },
                                new SearchableField("stateProvince")
                                {
                                    IsFilterable = true,             IsSortable                 = true, IsFacetable = true
                                },
                                new SearchableField("country")
                                {
                                    SynonymMapNames = new[] { synonymMapName },IsFilterable               = true, IsSortable  = true,IsFacetable          = true
                                },
                                new SearchableField("postalCode")
                                {
                                    IsFilterable = true,             IsSortable                 = true, IsFacetable = true
                                }
                            }
                        }
                    }
                };

                await indexClient.CreateIndexAsync(index);

                #endregion Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_CreateIndex

                // Make sure our synonym map gets deleted, which is not deleted when our
                // index is deleted when our SearchResources goes out of scope.
                cleanUpTasks.Push(() => indexClient.DeleteIndexAsync(indexName));

                #region Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_CreateDataSourceConnection
                // Create a new SearchIndexerClient
                SearchIndexerClient indexerClient = new SearchIndexerClient(endpoint, credential);
#if !SNIPPET
                indexerClient = resources.GetIndexerClient();
#endif

                string dataSourceConnectionName = "hotels";
#if !SNIPPET
                dataSourceConnectionName = Recording.Random.GetName();
#endif
                SearchIndexerDataSourceConnection dataSourceConnection = new SearchIndexerDataSourceConnection(
                    dataSourceConnectionName,
                    SearchIndexerDataSourceType.AzureBlob,
                    Environment.GetEnvironmentVariable("STORAGE_CONNECTION_STRING"),
                    new SearchIndexerDataContainer(Environment.GetEnvironmentVariable("STORAGE_CONTAINER")));

                await indexerClient.CreateDataSourceConnectionAsync(dataSourceConnection);

                #endregion Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_CreateDataSourceConnection

                // Make sure our data source gets deleted, which is not deleted when our
                // index is deleted when our SearchResources goes out of scope.
                cleanUpTasks.Push(() => indexerClient.DeleteDataSourceConnectionAsync(dataSourceConnectionName));

                #region Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_Skillset
                // Translate English descriptions to French.
                // See https://docs.microsoft.com/azure/search/cognitive-search-skill-text-translation for details of the Text Translation skill.
                TextTranslationSkill translationSkill = new TextTranslationSkill(
                    inputs: new[]
                {
                    new InputFieldMappingEntry("text")
                    {
                        Source = "/document/description"
                    }
                },
                    outputs: new[]
                {
                    new OutputFieldMappingEntry("translatedText")
                    {
                        TargetName = "descriptionFrTranslated"
                    }
                },
                    TextTranslationSkillLanguage.Fr)
                {
                    Name    = "descriptionFrTranslation",
                    Context = "/document",
                    DefaultFromLanguageCode = TextTranslationSkillLanguage.En
                };

                // Use the human-translated French description if available; otherwise, use the translated description.
                // See https://docs.microsoft.com/azure/search/cognitive-search-skill-conditional for details of the Conditional skill.
                ConditionalSkill conditionalSkill = new ConditionalSkill(
                    inputs: new[]
                {
                    new InputFieldMappingEntry("condition")
                    {
                        Source = "= $(/document/descriptionFr) == null"
                    },
                    new InputFieldMappingEntry("whenTrue")
                    {
                        Source = "/document/descriptionFrTranslated"
                    },
                    new InputFieldMappingEntry("whenFalse")
                    {
                        Source = "/document/descriptionFr"
                    }
                },
                    outputs: new[]
                {
                    new OutputFieldMappingEntry("output")
                    {
                        TargetName = "descriptionFrFinal"
                    }
                })
                {
                    Name    = "descriptionFrConditional",
                    Context = "/document",
                };

                // Create a SearchIndexerSkillset that processes those skills in the order given below.
                string skillsetName = "translations";
#if !SNIPPET
                skillsetName = Recording.Random.GetName();
#endif
                SearchIndexerSkillset skillset = new SearchIndexerSkillset(
                    skillsetName,
                    new SearchIndexerSkill[] { translationSkill, conditionalSkill })
                {
                    CognitiveServicesAccount = new CognitiveServicesAccountKey(
                        Environment.GetEnvironmentVariable("COGNITIVE_SERVICES_KEY"))
                };

                await indexerClient.CreateSkillsetAsync(skillset);

                #endregion Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_Skillset

                // Make sure our skillset gets deleted, which is not deleted when our
                // index is deleted when our SearchResources goes out of scope.
                cleanUpTasks.Push(() => indexerClient.DeleteSkillsetAsync(skillsetName));

                #region Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_CreateIndexer
                string indexerName = "hotels";
#if !SNIPPET
                indexerName = Recording.Random.GetName();
#endif
                SearchIndexer indexer = new SearchIndexer(
                    indexerName,
                    dataSourceConnectionName,
                    indexName)
                {
                    // We only want to index fields defined in our index, excluding descriptionFr if defined.
                    FieldMappings =
                    {
                        new FieldMapping("hotelId"),
                        new FieldMapping("hotelName"),
                        new FieldMapping("description"),
                        new FieldMapping("tags"),
                        new FieldMapping("address")
                    },
                    OutputFieldMappings =
                    {
                        new FieldMapping("/document/descriptionFrFinal")
                        {
                            TargetFieldName = "descriptionFr"
                        }
                    },
                    Parameters = new IndexingParameters
                    {
                        // Tell the indexer to parse each blob as a separate JSON document.
                        IndexingParametersConfiguration = new IndexingParametersConfiguration
                        {
                            ParsingMode = BlobIndexerParsingMode.Json
                        }
                    },
                    SkillsetName = skillsetName
                };

                // Create the indexer which, upon successful creation, also runs the indexer.
                await indexerClient.CreateIndexerAsync(indexer);

                #endregion Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_CreateIndexer

                // Make sure our indexer gets deleted, which is not deleted when our
                // index is deleted when our SearchResources goes out of scope.
                cleanUpTasks.Push(() => indexerClient.DeleteIndexerAsync(indexerName));

                // Wait till the indexer is done.
                await WaitForIndexingAsync(indexerClient, indexerName);

                #region Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_Query
                // Get a SearchClient from the SearchIndexClient to share its pipeline.
                SearchClient searchClient = indexClient.GetSearchClient(indexName);
#if !SNIPPET
                searchClient = InstrumentClient(new SearchClient(endpoint, indexName, credential, GetSearchClientOptions()));
#endif

                // Query for hotels with an ocean view.
                SearchResults <Hotel> results = await searchClient.SearchAsync <Hotel>("ocean view");

#if !SNIPPET
                bool found = false;
#endif
                await foreach (SearchResult <Hotel> result in results.GetResultsAsync())
                {
                    Hotel hotel = result.Document;
#if !SNIPPET
                    if (hotel.HotelId == "6")
                    {
                        Assert.IsNotNull(hotel.DescriptionFr); found = true;
                    }
#endif

                    Console.WriteLine($"{hotel.HotelName} ({hotel.HotelId})");
                    Console.WriteLine($"  Description (English): {hotel.Description}");
                    Console.WriteLine($"  Description (French):  {hotel.DescriptionFr}");
                }
                #endregion Snippet:Azure_Search_Tests_Samples_CreateIndexerAsync_Query

                Assert.IsTrue(found, "Expected hotel #6 not found in search results");
            }
            finally
            {
                // We want to await these individual to create a deterministic order for playing back tests.
                foreach (Func <Task> cleanUpTask in cleanUpTasks)
                {
                    await cleanUpTask();
                }
            }
        }
예제 #9
0
 public TaskData(byte[] bytes, SearchIndexer combinedIndex)
 {
     this.bytes         = bytes;
     this.combinedIndex = combinedIndex;
 }