public async Task Should_create_performance_hint_notification_when_exceeding_max_index_outputs() { var index = new UsersAndFriendsIndex(); var definition = index.CreateIndexDefinition(); using (var store = GetDocumentStore()) { var db = await GetDatabase(store.Database); db.Configuration.PerformanceHints.MaxWarnIndexOutputsPerDocument = 2; using (var session = store.OpenSession()) { var user1 = new User { Name = "user/1", Friends = new List <User> { new User { Name = "friend/1/1" }, new User { Name = "friend/1/2" } } }; var user2 = new User { Name = "user/2", Friends = new List <User> { new User { Name = "friend/2/1" }, new User { Name = "friend/2/2" }, new User { Name = "friend/2/3" } } }; var user3 = new User { Name = "user/3", Friends = new List <User> { new User { Name = "friend/3/1" } } }; session.Store(user1); session.Store(user2); session.Store(user3); session.SaveChanges(); } var notificationsQueue = new AsyncQueue <DynamicJsonValue>(); using (db.NotificationCenter.TrackActions(notificationsQueue, null)) { definition.Name = index.IndexName; store.Maintenance.Send(new PutIndexesOperation(new[] { definition })); WaitForIndexing(store); // we might have other notifications like StatsChanged Assert.True(notificationsQueue.Count > 0); Tuple <bool, DynamicJsonValue> performanceHint; do { performanceHint = await notificationsQueue.TryDequeueAsync(TimeSpan.Zero); } while (performanceHint.Item2["Type"].ToString() != NotificationType.PerformanceHint.ToString()); Assert.NotNull(performanceHint.Item2); Assert.Equal("Index 'UsersAndFriends' has produced more than 2 map results from a single document", performanceHint.Item2[nameof(PerformanceHint.Message)]); Assert.Equal("UsersAndFriends", performanceHint.Item2[nameof(PerformanceHint.Source)]); Assert.Equal(PerformanceHintType.Indexing, performanceHint.Item2[nameof(PerformanceHint.HintType)]); var details = performanceHint.Item2[nameof(PerformanceHint.Details)] as DynamicJsonValue; Assert.NotNull(details); Assert.Equal(1L, details[nameof(WarnIndexOutputsPerDocument.NumberOfExceedingDocuments)]); Assert.Equal(3, details[nameof(WarnIndexOutputsPerDocument.MaxNumberOutputsPerDocument)]); Assert.Equal("users/2-a", details[nameof(WarnIndexOutputsPerDocument.SampleDocumentId)]); } var indexStats = store.Maintenance.Send(new GetIndexStatisticsOperation(index.IndexName)); Assert.Equal(3, indexStats.MaxNumberOfOutputsPerDocument); } }
public void ShouldSkipDocumentsIfMaxIndexOutputsPerDocumentIsExceeded() { var index = new UsersAndFriendsIndex(); var definition = index.CreateIndexDefinition(); definition.Configuration.MaxIndexOutputsPerDocument = 2; using (var store = GetDocumentStore()) { using (var session = store.OpenSession()) { var user1 = new User { Name = "user/1", Friends = new List <User> { new User { Name = "friend/1/1" }, new User { Name = "friend/1/2" } } }; var user2 = new User { Name = "user/2", Friends = new List <User> { new User { Name = "friend/2/1" }, new User { Name = "friend/2/2" }, new User { Name = "friend/2/3" } } }; var user3 = new User { Name = "user/3", Friends = new List <User> { new User { Name = "friend/3/1" } } }; session.Store(user1); session.Store(user2); session.Store(user3); session.SaveChanges(); } store.DatabaseCommands.PutIndex(index.IndexName, definition); WaitForIndexing(store); SpinWait.SpinUntil(() => store.DatabaseCommands.GetIndexErrors(index.IndexName).Errors.Length > 0, 1000); var errors = store.DatabaseCommands.GetIndexErrors(index.IndexName); Assert.Equal(1, errors.Errors.Length); Assert.Contains("Index 'UsersAndFriends' has already produced 3 map results for a source document 'users/2'", errors.Errors[0].Error); using (var session = store.OpenSession()) { var results = session .Query <User, UsersAndFriendsIndex>() .ToList(); Assert.Equal(2, results.Count); Assert.True(results.Any(x => x.Name == "user/1")); Assert.True(results.Any(x => x.Name == "user/3")); } } }
public async Task Should_create_performance_hint_notification_when_exceeding_max_index_outputs() { var index = new UsersAndFriendsIndex(); var definition = index.CreateIndexDefinition(); using (var store = GetDocumentStore()) { var db = await GetDatabase(store.Database); db.Configuration.PerformanceHints.MaxWarnIndexOutputsPerDocument = 2; using (var session = store.OpenSession()) { var user1 = new User { Name = "user/1", Friends = new List <User> { new User { Name = "friend/1/1" }, new User { Name = "friend/1/2" } } }; var user2 = new User { Name = "user/2", Friends = new List <User> { new User { Name = "friend/2/1" }, new User { Name = "friend/2/2" }, new User { Name = "friend/2/3" } } }; var user3 = new User { Name = "user/3", Friends = new List <User> { new User { Name = "friend/3/1" } } }; session.Store(user1); session.Store(user2); session.Store(user3); session.SaveChanges(); } var notificationsQueue = new AsyncQueue <Notification>(); using (db.NotificationCenter.TrackActions(notificationsQueue, null)) { definition.Name = index.IndexName; store.Admin.Send(new PutIndexesOperation(new[] { definition })); WaitForIndexing(store); Assert.Equal(1, notificationsQueue.Count); var performanceHint = await notificationsQueue.DequeueAsync() as PerformanceHint; Assert.NotNull(performanceHint); Assert.Equal("Index 'UsersAndFriends' has produced more than 2 map results from a single document", performanceHint.Message); Assert.Equal("UsersAndFriends", performanceHint.Source); Assert.Equal(PerformanceHintType.Indexing, performanceHint.HintType); var details = performanceHint.Details as WarnIndexOutputsPerDocument; Assert.NotNull(details); Assert.Equal(1, details.NumberOfExceedingDocuments); Assert.Equal(3, details.MaxNumberOutputsPerDocument); //TODO:Need to invastigate why id is returning as lowered Assert.Equal("users/2-a", details.SampleDocumentId); } var indexStats = store.Admin.Send(new GetIndexStatisticsOperation(index.IndexName)); Assert.Equal(3, indexStats.MaxNumberOfOutputsPerDocument); } }
public async Task Should_create_performance_hint_notification_when_exceeding_max_index_outputs() { var index = new UsersAndFriendsIndex(); var definition = index.CreateIndexDefinition(); using (var store = GetDocumentStore()) { var db = await GetDatabase(store.Database); db.Configuration.PerformanceHints.MaxWarnIndexOutputsPerDocument = 2; using (var session = store.OpenSession()) { var user1 = new User { Name = "user/1", Friends = new List <User> { new User { Name = "friend/1/1" }, new User { Name = "friend/1/2" } } }; var user2 = new User { Name = "user/2", Friends = new List <User> { new User { Name = "friend/2/1" }, new User { Name = "friend/2/2" }, new User { Name = "friend/2/3" } } }; var user3 = new User { Name = "user/3", Friends = new List <User> { new User { Name = "friend/3/1" } } }; session.Store(user1); session.Store(user2); session.Store(user3); session.SaveChanges(); } var notificationsQueue = new AsyncQueue <DynamicJsonValue>(); using (db.NotificationCenter.TrackActions(notificationsQueue, null)) { definition.Name = index.IndexName; store.Maintenance.Send(new PutIndexesOperation(new[] { definition })); Indexes.WaitForIndexing(store); // we might have other notifications like StatsChanged Assert.True(WaitForValue(() => notificationsQueue.Count > 0, true, interval: 100)); Tuple <bool, DynamicJsonValue> performanceHint; do { performanceHint = await notificationsQueue.TryDequeueAsync(TimeSpan.Zero); } while (performanceHint.Item2["Type"].ToString() != NotificationType.PerformanceHint.ToString()); Assert.NotNull(performanceHint.Item2); Assert.Equal("Number of map results produced by an index exceeds the performance hint configuration key (MaxIndexOutputsPerDocument).", performanceHint.Item2[nameof(PerformanceHint.Message)]); Assert.Equal(PerformanceHintType.Indexing, performanceHint.Item2[nameof(PerformanceHint.HintType)]); var details = performanceHint.Item2[nameof(PerformanceHint.Details)] as DynamicJsonValue; Assert.NotNull(details); var warnings = details[nameof(WarnIndexOutputsPerDocument.Warnings)] as DynamicJsonValue; Assert.NotNull(warnings); Assert.Contains(warnings.Properties.ToArray()[0].Name, "UsersAndFriends"); var indexWarningsArray = (warnings["UsersAndFriends"] as DynamicJsonArray).ToArray(); var indexWarning = indexWarningsArray[0] as DynamicJsonValue; var numberOfExceedingDocs = indexWarning[nameof(WarnIndexOutputsPerDocument.WarningDetails.NumberOfExceedingDocuments)]; var numberOfOutputsPerDoc = indexWarning[nameof(WarnIndexOutputsPerDocument.WarningDetails.MaxNumberOutputsPerDocument)]; var sampleDoc = indexWarning[nameof(WarnIndexOutputsPerDocument.WarningDetails.SampleDocumentId)]; Assert.Equal(1L, numberOfExceedingDocs); Assert.Equal(3, numberOfOutputsPerDoc); Assert.Equal("users/2-A", sampleDoc); } Assert.Equal(3, WaitForValue(() => { var indexStats = store.Maintenance.Send(new GetIndexStatisticsOperation(index.IndexName)); return(indexStats.MaxNumberOfOutputsPerDocument); }, 3)); } }