From e3548efed4f2e0d0bf49c0b8f98e024c684c2ab3 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 28 Nov 2018 14:17:11 +1100 Subject: [PATCH] Uses IIndexPopulator to populate/rebuild indexes --- src/Umbraco.Core/Constants-Indexes.cs | 21 ++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + src/Umbraco.Examine/ContentIndexPopulator.cs | 16 ++++++---- src/Umbraco.Examine/IIndexPopulator.cs | 9 +++--- src/Umbraco.Examine/IndexPopulator.cs | 32 +++++++++++++++++++ src/Umbraco.Examine/IndexRebuilder.cs | 30 ++++++----------- src/Umbraco.Examine/MediaIndexPopulator.cs | 13 ++++++-- src/Umbraco.Examine/MemberIndexPopulator.cs | 15 ++++++--- src/Umbraco.Examine/Umbraco.Examine.csproj | 1 + src/Umbraco.Web/Search/ExamineComponent.cs | 1 - .../Search/UmbracoIndexesBuilder.cs | 30 ++++------------- 11 files changed, 105 insertions(+), 64 deletions(-) create mode 100644 src/Umbraco.Core/Constants-Indexes.cs create mode 100644 src/Umbraco.Examine/IndexPopulator.cs diff --git a/src/Umbraco.Core/Constants-Indexes.cs b/src/Umbraco.Core/Constants-Indexes.cs new file mode 100644 index 0000000000..d9d86884c4 --- /dev/null +++ b/src/Umbraco.Core/Constants-Indexes.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace Umbraco.Core +{ + public static partial class Constants + { + + public static class UmbracoIndexes + { + public const string InternalIndexName = InternalIndexPath + "Indexer"; + public const string ExternalIndexName = ExternalIndexPath + "Indexer"; + public const string MembersIndexName = MembersIndexPath + "Indexer"; + + public const string InternalIndexPath = "Internal"; + public const string ExternalIndexPath = "External"; + public const string MembersIndexPath = "Members"; + + } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index c54f14423b..7e99042562 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -313,6 +313,7 @@ + diff --git a/src/Umbraco.Examine/ContentIndexPopulator.cs b/src/Umbraco.Examine/ContentIndexPopulator.cs index 211e2d51de..c84b251786 100644 --- a/src/Umbraco.Examine/ContentIndexPopulator.cs +++ b/src/Umbraco.Examine/ContentIndexPopulator.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Linq; using Examine; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Core.Persistence; @@ -13,7 +15,7 @@ namespace Umbraco.Examine /// /// Performs the data lookups required to rebuild a content index /// - public class ContentIndexPopulator : IIndexPopulator + public class ContentIndexPopulator : IndexPopulator { private readonly IContentService _contentService; private readonly IValueSetBuilder _contentValueSetBuilder; @@ -54,9 +56,12 @@ namespace Umbraco.Examine _publishedQuery = sqlContext.Query().Where(x => x.Published); _supportUnpublishedContent = supportUnpublishedContent; _parentId = parentId; + + RegisterIndex(Constants.UmbracoIndexes.InternalIndexName); + RegisterIndex(Constants.UmbracoIndexes.ExternalIndexName); } - public void Populate(params IIndexer[] indexes) + protected override void PopulateIndexes(IEnumerable indexes) { const int pageSize = 10000; var pageIndex = 0; @@ -70,22 +75,21 @@ namespace Umbraco.Examine do { - long total; - if (_supportUnpublishedContent) { - content = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total).ToArray(); + content = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out _).ToArray(); } else { //add the published filter //note: We will filter for published variants in the validator - content = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, + content = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out _, _publishedQuery, Ordering.By("Path", Direction.Ascending)).ToArray(); } if (content.Length > 0) { + // ReSharper disable once PossibleMultipleEnumeration foreach (var index in indexes) index.IndexItems(_contentValueSetBuilder.GetValueSets(content)); } diff --git a/src/Umbraco.Examine/IIndexPopulator.cs b/src/Umbraco.Examine/IIndexPopulator.cs index fd71b3bb53..f4c27902eb 100644 --- a/src/Umbraco.Examine/IIndexPopulator.cs +++ b/src/Umbraco.Examine/IIndexPopulator.cs @@ -1,16 +1,15 @@ -using Examine; +using System.Collections.Generic; +using Examine; namespace Umbraco.Examine { - /// - /// Populates indexes with data - /// public interface IIndexPopulator { /// - /// Populates indexes with data + /// Populate indexers /// /// void Populate(params IIndexer[] indexes); } + } diff --git a/src/Umbraco.Examine/IndexPopulator.cs b/src/Umbraco.Examine/IndexPopulator.cs new file mode 100644 index 0000000000..af5301c230 --- /dev/null +++ b/src/Umbraco.Examine/IndexPopulator.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Linq; +using Examine; + +namespace Umbraco.Examine +{ + public abstract class IndexPopulator : IIndexPopulator + { + private readonly HashSet _registeredIndexes = new HashSet(); + + /// + /// Registers an index for this populator + /// + /// + public void RegisterIndex(string indexName) + { + _registeredIndexes.Add(indexName); + } + + /// + /// Returns a list of index names that his populate is associated with + /// + public IEnumerable RegisteredIndexes => _registeredIndexes; + + public void Populate(params IIndexer[] indexes) + { + PopulateIndexes(indexes.Where(x => RegisteredIndexes.Contains(x.Name))); + } + + protected abstract void PopulateIndexes(IEnumerable indexes); + } +} \ No newline at end of file diff --git a/src/Umbraco.Examine/IndexRebuilder.cs b/src/Umbraco.Examine/IndexRebuilder.cs index 5488fa2583..92b30537bf 100644 --- a/src/Umbraco.Examine/IndexRebuilder.cs +++ b/src/Umbraco.Examine/IndexRebuilder.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Examine; namespace Umbraco.Examine @@ -8,41 +9,28 @@ namespace Umbraco.Examine /// public class IndexRebuilder { + private readonly IEnumerable _populators; public IExamineManager ExamineManager { get; } - private readonly ContentIndexPopulator _contentIndexPopulator; - private readonly MediaIndexPopulator _mediaIndexPopulator; - public IndexRebuilder(IExamineManager examineManager, ContentIndexPopulator contentIndexPopulator, MediaIndexPopulator mediaIndexPopulator) + public IndexRebuilder(IExamineManager examineManager, IEnumerable populators) { + _populators = populators; ExamineManager = examineManager; - _contentIndexPopulator = contentIndexPopulator; - _mediaIndexPopulator = mediaIndexPopulator; } public void RebuildIndexes(bool onlyEmptyIndexes) { var indexes = (onlyEmptyIndexes ? ExamineManager.IndexProviders.Values.Where(x => x.IndexExists()) - : ExamineManager.IndexProviders.Values).ToList(); - - var contentIndexes = indexes.Where(x => x is IUmbracoContentIndexer).ToArray(); - var mediaIndexes = indexes.Where(x => x is IUmbracoContentIndexer).ToArray(); - var nonUmbracoIndexes = indexes.Except(contentIndexes).Except(mediaIndexes).ToArray(); + : ExamineManager.IndexProviders.Values).ToArray(); foreach(var index in indexes) index.CreateIndex(); // clear the index - //reindex all content/media indexes with the same data source/lookup - _contentIndexPopulator.Populate(contentIndexes); - _mediaIndexPopulator.Populate(mediaIndexes); - - //then do the rest - foreach (var index in nonUmbracoIndexes) + foreach (var populator in _populators) { - index.CreateIndex(); - //TODO: How to rebuild? - } - + populator.Populate(indexes); + } } } } diff --git a/src/Umbraco.Examine/MediaIndexPopulator.cs b/src/Umbraco.Examine/MediaIndexPopulator.cs index 0dfd9b1bc5..99fa22acea 100644 --- a/src/Umbraco.Examine/MediaIndexPopulator.cs +++ b/src/Umbraco.Examine/MediaIndexPopulator.cs @@ -1,5 +1,7 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Examine; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; @@ -8,7 +10,7 @@ namespace Umbraco.Examine /// /// Performs the data lookups required to rebuild a media index /// - public class MediaIndexPopulator : IIndexPopulator + public class MediaIndexPopulator : IndexPopulator { private readonly int? _parentId; private readonly IMediaService _mediaService; @@ -35,9 +37,12 @@ namespace Umbraco.Examine _parentId = parentId; _mediaService = mediaService; _mediaValueSetBuilder = mediaValueSetBuilder; + + RegisterIndex(Constants.UmbracoIndexes.InternalIndexName); + RegisterIndex(Constants.UmbracoIndexes.ExternalIndexName); } - public void Populate(params IIndexer[] indexes) + protected override void PopulateIndexes(IEnumerable indexes) { const int pageSize = 10000; var pageIndex = 0; @@ -57,6 +62,7 @@ namespace Umbraco.Examine if (media.Length > 0) { + // ReSharper disable once PossibleMultipleEnumeration foreach (var index in indexes) index.IndexItems(_mediaValueSetBuilder.GetValueSets(media)); } @@ -64,5 +70,6 @@ namespace Umbraco.Examine pageIndex++; } while (media.Length == pageSize); } + } } diff --git a/src/Umbraco.Examine/MemberIndexPopulator.cs b/src/Umbraco.Examine/MemberIndexPopulator.cs index cbe763e2c1..79dd31436b 100644 --- a/src/Umbraco.Examine/MemberIndexPopulator.cs +++ b/src/Umbraco.Examine/MemberIndexPopulator.cs @@ -1,11 +1,13 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Examine; +using Lucene.Net.Util; using Umbraco.Core.Models; using Umbraco.Core.Services; namespace Umbraco.Examine { - public class MemberIndexPopulator: IIndexPopulator + public class MemberIndexPopulator : IndexPopulator { private readonly IMemberService _memberService; private readonly IValueSetBuilder _valueSetBuilder; @@ -14,8 +16,10 @@ namespace Umbraco.Examine { _memberService = memberService; _valueSetBuilder = valueSetBuilder; + + RegisterIndex(Core.Constants.UmbracoIndexes.MembersIndexName); } - public void Populate(params IIndexer[] indexes) + protected override void PopulateIndexes(IEnumerable indexes) { const int pageSize = 1000; var pageIndex = 0; @@ -31,10 +35,11 @@ namespace Umbraco.Examine if (members.Length > 0) { + // ReSharper disable once PossibleMultipleEnumeration foreach (var index in indexes) index.IndexItems(_valueSetBuilder.GetValueSets(members)); - } - + } + pageIndex++; } while (members.Length == pageSize); } diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index f5c85fada3..0bb12ae00a 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -64,6 +64,7 @@ + diff --git a/src/Umbraco.Web/Search/ExamineComponent.cs b/src/Umbraco.Web/Search/ExamineComponent.cs index 64a69a43fc..2b2a1f1938 100644 --- a/src/Umbraco.Web/Search/ExamineComponent.cs +++ b/src/Umbraco.Web/Search/ExamineComponent.cs @@ -829,7 +829,6 @@ namespace Umbraco.Web.Search public void Dispose() { - throw new NotImplementedException(); } public void Run() diff --git a/src/Umbraco.Web/Search/UmbracoIndexesBuilder.cs b/src/Umbraco.Web/Search/UmbracoIndexesBuilder.cs index f8a6a16ec5..339fa2f2be 100644 --- a/src/Umbraco.Web/Search/UmbracoIndexesBuilder.cs +++ b/src/Umbraco.Web/Search/UmbracoIndexesBuilder.cs @@ -26,36 +26,20 @@ namespace Umbraco.Web.Search //TODO: we should inject the different IValueSetValidator so devs can just register them instead of overriding this class? public UmbracoIndexesBuilder(ProfilingLogger profilingLogger, - IValueSetBuilder memberValueSetBuilder, - ContentIndexPopulator contentIndexPopulator, - PublishedContentIndexPopulator publishedContentIndexPopulator, - MediaIndexPopulator mediaIndexPopulator, ILocalizationService languageService, IPublicAccessService publicAccessService, IMemberService memberService) { ProfilingLogger = profilingLogger ?? throw new System.ArgumentNullException(nameof(profilingLogger)); - MemberValueSetBuilder = memberValueSetBuilder ?? throw new System.ArgumentNullException(nameof(memberValueSetBuilder)); - ContentIndexPopulator = contentIndexPopulator; - PublishedContentIndexPopulator = publishedContentIndexPopulator; - MediaIndexPopulator = mediaIndexPopulator; LanguageService = languageService ?? throw new System.ArgumentNullException(nameof(languageService)); PublicAccessService = publicAccessService ?? throw new System.ArgumentNullException(nameof(publicAccessService)); MemberService = memberService ?? throw new System.ArgumentNullException(nameof(memberService)); } protected ProfilingLogger ProfilingLogger { get; } - protected IValueSetBuilder MemberValueSetBuilder { get; } - protected ContentIndexPopulator ContentIndexPopulator { get; } - protected PublishedContentIndexPopulator PublishedContentIndexPopulator { get; } - protected MediaIndexPopulator MediaIndexPopulator { get; } protected ILocalizationService LanguageService { get; } protected IPublicAccessService PublicAccessService { get; } protected IMemberService MemberService { get; } - - public const string InternalIndexPath = "Internal"; - public const string ExternalIndexPath = "External"; - public const string MembersIndexPath = "Members"; /// /// By default these are the member fields we index @@ -70,19 +54,19 @@ namespace Umbraco.Web.Search { return new [] { - CreateContentIndex(InternalIndexPath, new UmbracoContentIndexerOptions(true, true, null), new CultureInvariantWhitespaceAnalyzer()), - CreateContentIndex(ExternalIndexPath, new UmbracoContentIndexerOptions(false, false, null), new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)), + CreateContentIndex(Constants.UmbracoIndexes.InternalIndexName, Constants.UmbracoIndexes.InternalIndexPath, new UmbracoContentIndexerOptions(true, true, null), new CultureInvariantWhitespaceAnalyzer()), + CreateContentIndex(Constants.UmbracoIndexes.ExternalIndexName, Constants.UmbracoIndexes.ExternalIndexPath, new UmbracoContentIndexerOptions(false, false, null), new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)), CreateMemberIndex() }; } - private IIndexer CreateContentIndex(string name, UmbracoContentIndexerOptions options, Analyzer analyzer) + private IIndexer CreateContentIndex(string name, string path, UmbracoContentIndexerOptions options, Analyzer analyzer) { var index = new UmbracoContentIndexer( - $"{name}Indexer", + name, //fixme - how to deal with languages like in UmbracoContentIndexer.CreateFieldValueTypes UmbracoExamineIndexer.UmbracoIndexFieldDefinitions, - GetFileSystemLuceneDirectory(name), + GetFileSystemLuceneDirectory(path), analyzer, ProfilingLogger, LanguageService, @@ -94,10 +78,10 @@ namespace Umbraco.Web.Search private IIndexer CreateMemberIndex() { var index = new UmbracoMemberIndexer( - $"{MembersIndexPath}Indexer", + Constants.UmbracoIndexes.MembersIndexName, //fixme - how to deal with languages like in UmbracoContentIndexer.CreateFieldValueTypes UmbracoExamineIndexer.UmbracoIndexFieldDefinitions, - GetFileSystemLuceneDirectory(MembersIndexPath), + GetFileSystemLuceneDirectory(Constants.UmbracoIndexes.MembersIndexPath), new CultureInvariantWhitespaceAnalyzer(), ProfilingLogger, GetMemberValueSetValidator());