public async Task UpdateIndexAsync(LuceneIndexSettings settings) { var document = await LoadDocumentAsync(); document.LuceneIndexSettings[settings.IndexName] = settings; await _documentManager.UpdateAsync(document); }
public async Task UpdateIndexAsync(LuceneIndexSettings settings) { if (settings.IsReadonly) { throw new ArgumentException("The object is read-only"); } var document = await LoadDocumentAsync(); document.LuceneIndexSettings[settings.IndexName] = settings; Session.Save(document); _signal.DeferredSignalToken(CacheKey); }
public async Task <ActionResult> Edit(string indexName = null) { var IsCreate = String.IsNullOrWhiteSpace(indexName); var settings = new LuceneIndexSettings(); if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes)) { return(Forbid()); } if (!IsCreate) { settings = await _luceneIndexSettingsService.GetSettingsAsync(indexName); if (settings == null) { return(NotFound()); } } var model = new LuceneIndexSettingsViewModel { IsCreate = IsCreate, IndexName = IsCreate ? "" : settings.IndexName, AnalyzerName = IsCreate ? "standardanalyzer" : settings.AnalyzerName, IndexLatest = settings.IndexLatest, Culture = settings.Culture, Cultures = CultureInfo.GetCultures(CultureTypes.AllCultures) .Select(x => new SelectListItem { Text = x.Name + " (" + x.DisplayName + ")", Value = x.Name }).Prepend(new SelectListItem { Text = S["Any culture"], Value = "any" }), Analyzers = _luceneAnalyzerManager.GetAnalyzers() .Select(x => new SelectListItem { Text = x.Name, Value = x.Name }), IndexedContentTypes = IsCreate ? _contentDefinitionManager.ListTypeDefinitions() .Select(x => x.Name).ToArray() : settings.IndexedContentTypes }; return(View(model)); }
public async Task UpdateIndexAsync(LuceneIndexSettings settings) { if (settings.IsReadonly) { throw new ArgumentException("The object is read-only"); } using (var session = _store.CreateSession()) { var document = await LoadDocumentAsync(session); document.LuceneIndexSettings[settings.IndexName] = settings; session.Save(document); await session.CommitAsync(); } _signal.SignalToken(CacheKey); }
public async Task <ActionResult> EditPost(LuceneIndexSettingsViewModel model, string[] indexedContentTypes) { if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes)) { return(Forbid()); } ValidateModel(model); if (model.IsCreate) { if (_luceneIndexManager.Exists(model.IndexName)) { ModelState.AddModelError(nameof(LuceneIndexSettingsViewModel.IndexName), S["An index named {0} already exists.", model.IndexName]); } } else { if (!_luceneIndexManager.Exists(model.IndexName)) { ModelState.AddModelError(nameof(LuceneIndexSettingsViewModel.IndexName), S["An index named {0} doesn't exist.", model.IndexName]); } } if (!ModelState.IsValid) { model.Cultures = CultureInfo.GetCultures(CultureTypes.AllCultures) .Select(x => new SelectListItem { Text = x.Name + " (" + x.DisplayName + ")", Value = x.Name }).Prepend(new SelectListItem { Text = S["Any culture"], Value = "any" }); model.Analyzers = _luceneAnalyzerManager.GetAnalyzers() .Select(x => new SelectListItem { Text = x.Name, Value = x.Name }); return(View(model)); } if (model.IsCreate) { try { var settings = new LuceneIndexSettings { IndexName = model.IndexName, AnalyzerName = model.AnalyzerName, IndexLatest = model.IndexLatest, IndexedContentTypes = indexedContentTypes, Culture = model.Culture ?? "" }; // We call Rebuild in order to reset the index state cursor too in case the same index // name was also used previously. await _luceneIndexingService.CreateIndexAsync(settings); } catch (Exception e) { _notifier.Error(H["An error occurred while creating the index."]); _logger.LogError(e, "An error occurred while creating an index."); return(View(model)); } _notifier.Success(H["Index <em>{0}</em> created successfully.", model.IndexName]); } else { try { var settings = new LuceneIndexSettings { IndexName = model.IndexName, AnalyzerName = model.AnalyzerName, IndexLatest = model.IndexLatest, IndexedContentTypes = indexedContentTypes, Culture = model.Culture ?? "" }; await _luceneIndexingService.UpdateIndexAsync(settings); } catch (Exception e) { _notifier.Error(H["An error occurred while editing the index."]); _logger.LogError(e, "An error occurred while editing an index."); return(View(model)); } _notifier.Success(H["Index <em>{0}</em> modified successfully, <strong>please consider doing a rebuild on the index.</strong>", model.IndexName]); } return(RedirectToAction("Index")); }
public async Task ProcessContentItemsAsync(string indexName = default) { // TODO: Lock over the filesystem in case two instances get a command to rebuild the index concurrently. var allIndices = new Dictionary <string, int>(); var lastTaskId = Int32.MaxValue; IEnumerable <LuceneIndexSettings> indexSettingsList = null; if (String.IsNullOrEmpty(indexName)) { indexSettingsList = await _luceneIndexSettingsService.GetSettingsAsync(); if (!indexSettingsList.Any()) { return; } // Find the lowest task id to process foreach (var indexSetting in indexSettingsList) { var taskId = _indexingState.GetLastTaskId(indexSetting.IndexName); lastTaskId = Math.Min(lastTaskId, taskId); allIndices.Add(indexSetting.IndexName, taskId); } } else { var settings = await _luceneIndexSettingsService.GetSettingsAsync(indexName); if (settings == null) { return; } indexSettingsList = new LuceneIndexSettings[1] { settings }.AsEnumerable(); var taskId = _indexingState.GetLastTaskId(indexName); lastTaskId = Math.Min(lastTaskId, taskId); allIndices.Add(indexName, taskId); } if (allIndices.Count == 0) { return; } var batch = Array.Empty <IndexingTask>(); do { // Create a scope for the content manager var shellScope = await _shellHost.GetScopeAsync(_shellSettings); await shellScope.UsingAsync(async scope => { // Load the next batch of tasks batch = (await _indexingTaskManager.GetIndexingTasksAsync(lastTaskId, BatchSize)).ToArray(); if (!batch.Any()) { return; } var contentManager = scope.ServiceProvider.GetRequiredService <IContentManager>(); var indexHandlers = scope.ServiceProvider.GetServices <IContentItemIndexHandler>(); // Pre-load all content items to prevent SELECT N+1 var updatedContentItemIds = batch .Where(x => x.Type == IndexingTaskTypes.Update) .Select(x => x.ContentItemId) .ToArray(); var allPublished = await contentManager.GetAsync(updatedContentItemIds); var allLatest = await contentManager.GetAsync(updatedContentItemIds, latest: true); // Group all DocumentIndex by index to batch update them var updatedDocumentsByIndex = new Dictionary <string, List <DocumentIndex> >(); foreach (var index in allIndices) { updatedDocumentsByIndex[index.Key] = new List <DocumentIndex>(); } if (indexName != null) { indexSettingsList = indexSettingsList.Where(x => x.IndexName == indexName); } var needLatest = indexSettingsList.FirstOrDefault(x => x.IndexLatest) != null; var needPublished = indexSettingsList.FirstOrDefault(x => !x.IndexLatest) != null; var settingsByIndex = indexSettingsList.ToDictionary(x => x.IndexName, x => x); foreach (var task in batch) { if (task.Type == IndexingTaskTypes.Update) { BuildIndexContext publishedIndexContext = null, latestIndexContext = null; if (needPublished) { var contentItem = await contentManager.GetAsync(task.ContentItemId); if (contentItem != null) { publishedIndexContext = new BuildIndexContext(new DocumentIndex(task.ContentItemId), contentItem, new string[] { contentItem.ContentType }); await indexHandlers.InvokeAsync(x => x.BuildIndexAsync(publishedIndexContext), _logger); } } if (needLatest) { var contentItem = await contentManager.GetAsync(task.ContentItemId, VersionOptions.Latest); if (contentItem != null) { latestIndexContext = new BuildIndexContext(new DocumentIndex(task.ContentItemId), contentItem, new string[] { contentItem.ContentType }); await indexHandlers.InvokeAsync(x => x.BuildIndexAsync(latestIndexContext), _logger); } } // Update the document from the index if its lastIndexId is smaller than the current task id. foreach (var index in allIndices) { if (index.Value >= task.Id || !settingsByIndex.TryGetValue(index.Key, out var settings)) { continue; } var context = !settings.IndexLatest ? publishedIndexContext : latestIndexContext; //We index only if we actually found a content item in the database if (context == null) { //TODO purge these content items from IndexingTask table continue; } var cultureAspect = await contentManager.PopulateAspectAsync <CultureAspect>(context.ContentItem); var culture = cultureAspect.HasCulture ? cultureAspect.Culture.Name : null; var ignoreIndexedCulture = settings.Culture == "any" ? false : culture != settings.Culture; // Ignore if the content item content type or culture is not indexed in this index if (!settings.IndexedContentTypes.Contains(context.ContentItem.ContentType) || ignoreIndexedCulture) { continue; } updatedDocumentsByIndex[index.Key].Add(context.DocumentIndex); } } } // Delete all the existing documents foreach (var index in updatedDocumentsByIndex) { var deletedDocuments = updatedDocumentsByIndex[index.Key].Select(x => x.ContentItemId); await _indexManager.DeleteDocumentsAsync(index.Key, deletedDocuments); } // Submits all the new documents to the index foreach (var index in updatedDocumentsByIndex) { await _indexManager.StoreDocumentsAsync(index.Key, updatedDocumentsByIndex[index.Key]); } // Update task ids lastTaskId = batch.Last().Id; foreach (var indexStatus in allIndices) { if (indexStatus.Value < lastTaskId) { _indexingState.SetLastTaskId(indexStatus.Key, lastTaskId); } } _indexingState.Update(); }, activateShell : false); } while (batch.Length == BatchSize); }
/// <summary> /// Update an existing index /// </summary> /// <returns></returns> public Task UpdateIndexAsync(LuceneIndexSettings indexSettings) { return(_luceneIndexSettingsService.UpdateIndexAsync(indexSettings)); }
/// <summary> /// Creates a new index /// </summary> /// <returns></returns> public async Task CreateIndexAsync(LuceneIndexSettings indexSettings) { await _luceneIndexSettingsService.UpdateIndexAsync(indexSettings); await RebuildIndexAsync(indexSettings.IndexName); }