Exemplo n.º 1
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 5
0
        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);
        }