public async Task ThrowsWhenGivenBadSuggesterName()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            string invalidName        = "Invalid suggester";
            RequestFailedException ex = await CatchAsync <RequestFailedException>(
                async() => await resources.GetQueryClient().SuggestAsync(
                    "hotel",
                    invalidName));

            Assert.AreEqual(400, ex.Status);
            StringAssert.StartsWith(
                $"The specified suggester name '{invalidName}' does not exist in this index definition.",
                ex.Message);
        }
示例#2
0
        public async Task ClientRequestIdRountrips()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            SearchServiceClient client = resources.GetServiceClient();
            Guid id = Recording.Random.NewGuid();
            Response <SearchServiceStatistics> response =
                await client.GetServiceStatisticsAsync(
                    new SearchRequestOptions { ClientRequestId = id });

            // TODO: #10604 - C# generator doesn't properly support ClientRequestId yet
            // (Assertion is here to remind us to fix this when we do - just
            // change to AreEqual and re-record)
            Assert.AreNotEqual(id.ToString(), response.GetRawResponse().ClientRequestId);
        }
        public async Task RegexSpecialCharsUnescapedThrows()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            SearchIndexClient      client = resources.GetQueryClient();
            RequestFailedException ex     = await CatchAsync <RequestFailedException>(
                async() => await client.SearchAsync(
                    @"/.*/.*/",
                    new SearchOptions {
                QueryType = SearchQueryType.Full
            }));

            Assert.AreEqual(400, ex.Status);
            StringAssert.StartsWith("Failed to parse query string at line 1, column 8.", ex.Message);
        }
        public async Task RecentlyIndexedDynamicDocument()
        {
            await using SearchResources resources = await SearchResources.CreateWithEmptyHotelsIndexAsync(this);

            Hotel document = SearchResources.TestDocuments[0];

            await resources.GetSearchClient().IndexDocumentsAsync(
                IndexDocumentsBatch.Upload(new[] { document.AsDocument() }));

            await resources.WaitForIndexingAsync();

            Response <Hotel> response = await resources.GetQueryClient().GetDocumentAsync <Hotel>(document.HotelId);

            Assert.AreEqual(document.HotelId, response.Value.HotelId);
        }
        public async Task RegexSpecialChars()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            Response <SearchResults <Hotel> > response =
                await resources.GetQueryClient().SearchAsync <Hotel>(
                    @"/\+\-\&\|\!\(\)\{\}\[\]\^\""\\~\*\?\:\\\//",
                    new SearchOptions {
                QueryType = SearchQueryType.Full
            });

            List <SearchResult <Hotel> > docs = await response.Value.GetResultsAsync().ToListAsync();

            Assert.AreEqual(0, docs.Count);
        }
        public async Task ThrowsWhenMalformed()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            SearchIndexClient      client = resources.GetQueryClient();
            RequestFailedException ex     = await CatchAsync <RequestFailedException>(
                async() => await client.GetDocumentAsync(
                    "3",
                    new GetDocumentOptions()
            {
                SelectedFields = new[] { "ThisFieldDoesNotExist" }
            }));

            Assert.AreEqual(400, ex.Status);
            StringAssert.StartsWith("Invalid expression: Could not find a property named 'ThisFieldDoesNotExist' on type 'search.document'.", ex.Message);
        }
示例#7
0
        public async Task Filter()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "po",
                    "sg",
                    new AutocompleteOptions
            {
                Mode   = AutocompleteMode.OneTerm,
                Filter = "search.in(hotelId, '6,7')"
            }),
                new[] { "polite" },
                new[] { "polite" });
        }
示例#8
0
        public async Task SizeTrimsResults()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "po",
                    "sg",
                    new AutocompleteOptions
            {
                Mode = AutocompleteMode.OneTerm,
                Size = 2
            }),
                new[] { "point", "police" },
                new[] { "point", "police" });
        }
示例#9
0
        public async Task ExcludesFieldsNotInSuggester()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "luxu",
                    "sg",
                    new AutocompleteOptions
            {
                Mode         = AutocompleteMode.OneTerm,
                SearchFields = new[] { "hotelName" }
            }),
                Enumerable.Empty <string>(),
                Enumerable.Empty <string>());
        }
示例#10
0
        public async Task OneTermWithContextWithFuzzy()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "very polit",
                    "sg",
                    new AutocompleteOptions
            {
                Mode             = AutocompleteMode.OneTermWithContext,
                UseFuzzyMatching = true
            }),
                new[] { "very polite", "very police" },
                new[] { "very polite", "very police" });
        }
示例#11
0
        public async Task StaticallyTypedDocuments()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "very po",
                    "sg",
                    new AutocompleteOptions
            {
                Mode             = AutocompleteMode.OneTerm,
                UseFuzzyMatching = false
            }),
                new[] { "point", "police", "polite", "pool", "popular" },
                new[] { "very point", "very police", "very polite", "very pool", "very popular" });
        }
示例#12
0
        public async Task TwoTermsWithFuzzy()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "mod",
                    "sg",
                    new AutocompleteOptions
            {
                Mode             = AutocompleteMode.TwoTerms,
                UseFuzzyMatching = true
            }),
                new[] { "model suites", "modern architecture", "modern stay", "morel coverings", "motel" },
                new[] { "model suites", "modern architecture", "modern stay", "morel coverings", "motel" });
        }
示例#13
0
        public async Task OneTermWithFuzzy()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "mod",
                    "sg",
                    new AutocompleteOptions
            {
                Mode             = AutocompleteMode.OneTerm,
                UseFuzzyMatching = true
            }),
                new[] { "model", "modern", "morel", "motel" },
                new[] { "model", "modern", "morel", "motel" });
        }
        public async Task Fuzzy()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            SuggestResults <Hotel> suggestions =
                await resources.GetQueryClient().SuggestAsync <Hotel>(
                    "hitel",
                    "sg",
                    new SuggestOptions {
                UseFuzzyMatching = true
            });

            Assert.NotNull(suggestions);
            Assert.NotNull(suggestions.Results);
            Assert.AreEqual(5, suggestions.Results.Count);
        }
        public async Task SizeTrimsResults()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            SuggestResults <Hotel> suggestions =
                await resources.GetQueryClient().SuggestAsync <Hotel>(
                    "hotel",
                    "sg",
                    new SuggestOptions
            {
                OrderBy = new string[] { "hotelId" },
                Size    = 3
            });

            AssertContainsIds(suggestions, "1", "10", "2");
        }
示例#16
0
        public async Task MultipleSelectedFields()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "mod",
                    "sg",
                    new AutocompleteOptions
            {
                Mode         = AutocompleteMode.OneTerm,
                SearchFields = new[] { "hotelName", "description" }
            }),
                new[] { "model", "modern" },
                new[] { "model", "modern" });
        }
        public async Task Filter()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            SuggestResults <Hotel> suggestions =
                await resources.GetQueryClient().SuggestAsync <Hotel>(
                    "hotel",
                    "sg",
                    new SuggestOptions
            {
                Filter = "rating gt 3 and lastRenovationDate gt 2000-01-01T00:00:00Z",
                // Use OrderBy so changes in ranking don't break the test
                OrderBy = new[] { "hotelId" }
            });

            AssertContainsIds(suggestions, "1", "5");
        }
示例#18
0
        public async Task FilterAndFuzzy()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "mod",
                    "sg",
                    new AutocompleteOptions
            {
                Mode             = AutocompleteMode.OneTerm,
                UseFuzzyMatching = true,
                Filter           = "hotelId ne '6' and (hotelName eq 'Modern Stay' or tags/any(t : t eq 'budget'))"
            }),
                new[] { "modern", "motel" },
                new[] { "modern", "motel" });
        }
        public async Task ThrowsWhenRequestIsMalformed()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            RequestFailedException ex = await CatchAsync <RequestFailedException>(
                async() => await resources.GetQueryClient().SuggestAsync(
                    "hotel",
                    "sg",
                    new SuggestOptions {
                OrderBy = new[] { "This is not a valid orderby." }
            }));

            Assert.AreEqual(400, ex.Status);
            StringAssert.StartsWith(
                "Invalid expression: Syntax error at position 7 in 'This is not a valid orderby.'",
                ex.Message);
        }
示例#20
0
        public async Task Filter()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            Response <SearchResults <Hotel> > response =
                await resources.GetQueryClient().SearchAsync <Hotel>(
                    null,
                    new SearchOptions
            {
                Filter = "rating gt 3 and lastRenovationDate gt 2000-01-01T00:00:00Z"
            });

            await AssertKeysEqual(
                response,
                h => h.Document.HotelId,
                "1", "5");
        }
示例#21
0
        public async Task KeyFieldAccessor_FetchIndex()
        {
            await using SearchResources resources = await SearchResources.CreateWithEmptyIndexAsync <SimpleDocument>(this);

            SearchClient client = resources.GetSearchClient();

            UnbuildableDocument[] data = UnbuildableDocument.GetDocuments(10);

            await using SearchIndexingBufferedSender <UnbuildableDocument> indexer =
                            client.CreateIndexingBufferedSender <UnbuildableDocument>();
            AssertNoFailures(indexer);
            await indexer.UploadDocumentsAsync(data);

            await indexer.FlushAsync();

            await WaitForDocumentCountAsync(resources.GetSearchClient(), data.Length);
        }
示例#22
0
        public async Task Convenience_MergeOrUpload()
        {
            await using SearchResources resources = await SearchResources.CreateWithEmptyIndexAsync <SimpleDocument>(this);

            SearchClient client = resources.GetSearchClient();

            SimpleDocument[] data = SimpleDocument.GetDocuments((int)(BatchSize * 1.5));

            await using SearchIndexingBufferedSender <SimpleDocument> indexer =
                            client.CreateIndexingBufferedSender(
                                new SearchIndexingBufferedSenderOptions <SimpleDocument>());
            AssertNoFailures(indexer);
            await indexer.MergeOrUploadDocumentsAsync(data);

            await indexer.FlushAsync();

            await WaitForDocumentCountAsync(resources.GetSearchClient(), data.Length);
        }
示例#23
0
        public async Task HitHighlighting()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            VerifyCompletions(
                await resources.GetQueryClient().AutocompleteAsync(
                    "po",
                    "sg",
                    new AutocompleteOptions
            {
                Mode             = AutocompleteMode.OneTerm,
                Filter           = "hotelName eq 'EconoStay' or hotelName eq 'Fancy Stay'",
                HighlightPreTag  = "<b>",
                HighlightPostTag = "</b>",
            }),
                new[] { "pool", "popular" },
                new[] { "<b>pool</b>", "<b>popular</b>" });
        }
示例#24
0
        public async Task Convenience_Merge()
        {
            await using SearchResources resources = await SearchResources.CreateWithEmptyIndexAsync <SimpleDocument>(this);

            SearchClient client = resources.GetSearchClient();

            SimpleDocument[] data = SimpleDocument.GetDocuments((int)(BatchSize * 1.5));

            await using SearchIndexingBufferedSender <SimpleDocument> indexer =
                            client.CreateIndexingBufferedSender(
                                new SearchIndexingBufferedSenderOptions <SimpleDocument>());
            ConcurrentQueue <IndexDocumentsAction <SimpleDocument> > failures = TrackFailures(indexer);
            await indexer.MergeDocumentsAsync(data);

            await indexer.FlushAsync();

            Assert.AreEqual(data.Length, failures.Count);
        }
示例#25
0
        public async Task Behavior_Split()
        {
            await using SearchResources resources = await SearchResources.CreateWithEmptyIndexAsync <SimpleDocument>(this);

            BatchingSearchClient client = GetBatchingSearchClient(resources);

            SimpleDocument[] data = SimpleDocument.GetDocuments(BatchSize);

            await using SearchIndexingBufferedSender <SimpleDocument> indexer =
                            client.CreateIndexingBufferedSender <SimpleDocument>();
            AssertNoFailures(indexer);
            client.SplitNextBatch = true;
            await indexer.UploadDocumentsAsync(data);

            await indexer.FlushAsync();

            await WaitForDocumentCountAsync(resources.GetSearchClient(), data.Length);
        }
示例#26
0
        public async Task Dispose_UndisposedNoCrash()
        {
            await using SearchResources resources = await SearchResources.CreateWithEmptyIndexAsync <SimpleDocument>(this);

            SearchClient client = resources.GetSearchClient();

            SimpleDocument[] data = SimpleDocument.GetDocuments((int)(BatchSize * 1.5));

            SearchIndexingBufferedSender <SimpleDocument> indexer =
                client.CreateIndexingBufferedSender(
                    new SearchIndexingBufferedSenderOptions <SimpleDocument>()
            {
                AutoFlush = false
            });

            AssertNoFailures(indexer);
            await indexer.UploadDocumentsAsync(data);
        }
        public async Task VerifyRoundtrip <T>(
            Func <T, string> getKey,
            T document,
            T expected = default,
            GetDocumentOptions options = null)
        {
            await using SearchResources resources = await SearchResources.CreateWithEmptyHotelsIndexAsync(this);

            await resources.GetIndexClient().IndexDocumentsAsync <T>(
                IndexDocumentsBatch.Upload <T>(new[] { document }));

            await resources.WaitForIndexingAsync();

            Response <T> response = await resources.GetQueryClient().GetDocumentAsync <T>(getKey(document), options);

            // Only validate expected properties
            AssertApproximate(expected ?? document, response.Value);
        }
示例#28
0
        public async Task Champion_FineGrainedErrors()
        {
            await using SearchResources resources = await SearchResources.CreateWithEmptyIndexAsync <SimpleDocument>(this);

            SearchClient client = resources.GetSearchClient();

            SimpleDocument[] data = SimpleDocument.GetDocuments(1000);

            // Don't touch the failures outside of the event handler until
            // we've finished flushing
            List <IndexingResult> failures = new List <IndexingResult>();

            await using SearchIndexingBufferedSender <SimpleDocument> indexer =
                            client.CreateIndexingBufferedSender <SimpleDocument>(
                                new SearchIndexingBufferedSenderOptions <SimpleDocument>
            {
                AutoFlush = false
            });
            indexer.ActionFailedAsync +=
                (IndexDocumentsAction <SimpleDocument> doc,
                 IndexingResult result,
                 Exception ex,
                 CancellationToken cancellationToken) =>
            {
                failures.Add(result);
                return(Task.CompletedTask);
            };

            await indexer.UploadDocumentsAsync(data.Take(500));

            await indexer.MergeDocumentsAsync(new[] { new SimpleDocument {
                                                          Id = "Fake"
                                                      } });

            await indexer.UploadDocumentsAsync(data.Skip(500));

            await indexer.FlushAsync();

            await WaitForDocumentCountAsync(resources.GetSearchClient(), 1000);

            Assert.AreEqual(1, failures.Count);
            Assert.AreEqual("Fake", failures[0].Key);
            Assert.AreEqual(404, failures[0].Status);
        }
示例#29
0
        public async Task SelectedFields()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            Response <SearchResults <Hotel> > response =
                await resources.GetQueryClient().SearchAsync <Hotel>(
                    "fancy luxury secret",
                    new SearchOptions
            {
                SearchFields = new[] { "category", "hotelName" },
                Select       = new[] { "hotelName", "rating", "address/city", "rooms/type" }
            });

            Hotel[] expectedDocs =
                new[]
            {
                new Hotel {
                    HotelName = "Fancy Stay", Rating = 5
                },
                new Hotel
                {
                    HotelName = "Secret Point Motel",
                    Rating    = 4,
                    Address   = new HotelAddress {
                        City = "New York"
                    },
                    Rooms = new[]
                    {
                        new HotelRoom {
                            Type = "Budget Room"
                        },
                        new HotelRoom {
                            Type = "Budget Room"
                        }
                    }
                }
            };
            List <SearchResult <Hotel> > actualDocs =
                await response.Value.GetResultsAsync().ToListAsync();

            CollectionAssert.AreEqual(
                expectedDocs.OrderBy(h => h.HotelName),
                actualDocs.Select(d => d.Document).OrderBy(h => h.HotelName));
        }
        public async Task IndexSharesPipeline()
        {
            await using SearchResources resources = await SearchResources.GetSharedHotelsIndexAsync(this);

            TestPipelinePolicy custom = new TestPipelinePolicy();

            Assert.AreEqual(0, custom.RequestCount);

            SearchClientOptions options = new SearchClientOptions(ServiceVersion);

            options.AddPolicy(custom, HttpPipelinePosition.PerCall);
            SearchServiceClient client = resources.GetServiceClient(options);

            SearchIndexClient index = client.GetSearchIndexClient(resources.IndexName);

            _ = await index.GetDocumentCountAsync();

            Assert.AreEqual(1, custom.RequestCount);
        }