Latest examine, updates for dashboard, adds UmbracoExamineIndexDiagnostics

This commit is contained in:
Shannon
2018-11-29 13:55:51 +11:00
parent dd571060b9
commit 340b8e6cef
38 changed files with 201 additions and 463 deletions

View File

@@ -1,11 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using Umbraco.Core.Logging;
namespace Umbraco.Core
{
@@ -14,6 +9,17 @@ namespace Umbraco.Core
///</summary>
public static class EnumerableExtensions
{
/// <summary>
/// Wraps this object instance into an IEnumerable{T} consisting of a single item.
/// </summary>
/// <typeparam name="T"> Type of the object. </typeparam>
/// <param name="item"> The instance that will be wrapped. </param>
/// <returns> An IEnumerable{T} consisting of a single item. </returns>
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
public static IEnumerable<IEnumerable<T>> InGroupsOf<T>(this IEnumerable<T> source, int groupSize)
{
if (source == null)

View File

@@ -22,7 +22,7 @@ namespace Umbraco.Examine
/// <inheritdoc />
public abstract IEnumerable<ValueSet> GetValueSets(params TContent[] content);
protected void AddPropertyValue(Property property, string culture, string segment, IDictionary<string, object[]> values)
protected void AddPropertyValue(Property property, string culture, string segment, IDictionary<string, IEnumerable<object>> values)
{
var editor = _propertyEditors[property.PropertyType.PropertyEditorAlias];
if (editor == null) return;
@@ -48,7 +48,7 @@ namespace Umbraco.Examine
if (values.TryGetValue(key, out var v))
values[key] = new List<object>(v) { val }.ToArray();
else
values.Add($"{keyVal.Key}{cultureSuffix}", new[] { val });
values.Add($"{keyVal.Key}{cultureSuffix}", val.Yield());
}
break;
default:
@@ -57,7 +57,7 @@ namespace Umbraco.Examine
if (values.TryGetValue(key, out var v))
values[key] = new List<object>(v) { val }.ToArray();
else
values.Add($"{keyVal.Key}{cultureSuffix}", new[] { val });
values.Add($"{keyVal.Key}{cultureSuffix}", val.Yield());
}
break;

View File

@@ -61,7 +61,7 @@ namespace Umbraco.Examine
RegisterIndex(Constants.UmbracoIndexes.ExternalIndexName);
}
protected override void PopulateIndexes(IEnumerable<IIndexer> indexes)
protected override void PopulateIndexes(IEnumerable<IIndex> indexes)
{
const int pageSize = 10000;
var pageIndex = 0;

View File

@@ -35,9 +35,9 @@ namespace Umbraco.Examine
var isVariant = c.ContentType.VariesByCulture();
var urlValue = c.GetUrlSegment(_urlSegmentProviders); //Always add invariant urlName
var values = new Dictionary<string, object[]>
var values = new Dictionary<string, IEnumerable<object>>
{
{"icon", new [] {c.ContentType.Icon}},
{"icon", c.ContentType.Icon.Yield()},
{UmbracoExamineIndexer.PublishedFieldName, new object[] {c.Published ? 1 : 0}}, //Always add invariant published value
{"id", new object[] {c.Id}},
{"key", new object[] {c.Key}},
@@ -47,12 +47,12 @@ namespace Umbraco.Examine
{"sortOrder", new object[] {c.SortOrder}},
{"createDate", new object[] {c.CreateDate}}, //Always add invariant createDate
{"updateDate", new object[] {c.UpdateDate}}, //Always add invariant updateDate
{"nodeName", new object[] {c.Name}}, //Always add invariant nodeName
{"urlName", new object[] {urlValue}}, //Always add invariant urlName
{"path", new object[] {c.Path}},
{"nodeName", c.Name.Yield()}, //Always add invariant nodeName
{"urlName", urlValue.Yield()}, //Always add invariant urlName
{"path", c.Path.Yield()},
{"nodeType", new object[] {c.ContentType.Id}},
{"creatorName", new object[] {c.GetCreatorProfile(_userService)?.Name ?? "??"}},
{"writerName", new object[] {c.GetWriterProfile(_userService)?.Name ?? "??"}},
{"creatorName", (c.GetCreatorProfile(_userService)?.Name ?? "??").Yield() },
{"writerName",(c.GetWriterProfile(_userService)?.Name ?? "??").Yield() },
{"writerID", new object[] {c.WriterId}},
{"template", new object[] {c.Template?.Id ?? 0}},
{UmbracoContentIndexer.VariesByCultureFieldName, new object[] {0}},
@@ -66,8 +66,8 @@ namespace Umbraco.Examine
{
var variantUrl = c.GetUrlSegment(_urlSegmentProviders, culture);
var lowerCulture = culture.ToLowerInvariant();
values[$"urlName_{lowerCulture}"] = new object[] { variantUrl };
values[$"nodeName_{lowerCulture}"] = new object[] { c.GetCultureName(culture) };
values[$"urlName_{lowerCulture}"] = variantUrl.Yield();
values[$"nodeName_{lowerCulture}"] = c.GetCultureName(culture).Yield();
values[$"{UmbracoExamineIndexer.PublishedFieldName}_{lowerCulture}"] = new object[] { c.IsCulturePublished(culture) ? 1 : 0 };
values[$"updateDate_{lowerCulture}"] = new object[] { c.GetUpdateDate(culture) };
}

View File

@@ -7,7 +7,7 @@ using Lucene.Net.Store;
namespace Umbraco.Examine
{
/// <summary>
/// Extension methods for the LuceneIndexer
/// Extension methods for the LuceneIndex
/// </summary>
internal static class ExamineExtensions
{
@@ -17,7 +17,7 @@ namespace Umbraco.Examine
/// <param name="indexer"></param>
/// <param name="ex">The exception returned if there was an error</param>
/// <returns></returns>
public static bool IsHealthy(this LuceneIndexer indexer, out Exception ex)
public static bool IsHealthy(this LuceneIndex indexer, out Exception ex)
{
try
{
@@ -39,7 +39,7 @@ namespace Umbraco.Examine
/// </summary>
/// <param name="indexer"></param>
/// <returns></returns>
public static int GetIndexDocumentCount(this LuceneIndexer indexer)
public static int GetIndexDocumentCount(this LuceneIndex indexer)
{
if (!((indexer.GetSearcher() as LuceneSearcher)?.GetLuceneSearcher() is IndexSearcher searcher))
return 0;
@@ -56,7 +56,7 @@ namespace Umbraco.Examine
/// </summary>
/// <param name="indexer"></param>
/// <returns></returns>
public static int GetIndexFieldCount(this LuceneIndexer indexer)
public static int GetIndexFieldCount(this LuceneIndex indexer)
{
if (!((indexer.GetSearcher() as LuceneSearcher)?.GetLuceneSearcher() is IndexSearcher searcher))
return 0;

View File

@@ -9,7 +9,7 @@ namespace Umbraco.Examine
/// Populate indexers
/// </summary>
/// <param name="indexes"></param>
void Populate(params IIndexer[] indexes);
void Populate(params IIndex[] indexes);
}
}

View File

@@ -2,11 +2,11 @@
namespace Umbraco.Examine
{
//TODO: Rethink this, need a better way of rebuilding
/// <summary>
/// A Marker interface for defining an Umbraco content indexer
/// </summary>
public interface IUmbracoContentIndexer : IIndexer
public interface IUmbracoContentIndexer : IIndex
{
}
}

View File

@@ -5,7 +5,7 @@ namespace Umbraco.Examine
/// <summary>
/// A Marker interface for defining an Umbraco indexer
/// </summary>
public interface IUmbracoIndexer : IIndexer
public interface IUmbracoIndexer : IIndex
{
/// <summary>
/// When set to true Umbraco will keep the index in sync with Umbraco data automatically

View File

@@ -6,7 +6,7 @@ namespace Umbraco.Examine
/// <summary>
/// A Marker interface for defining an Umbraco media indexer
/// </summary>
public interface IUmbracoMediaIndexer : IIndexer
public interface IUmbracoMediaIndexer : IIndex
{
}
}

View File

@@ -22,11 +22,11 @@ namespace Umbraco.Examine
/// </summary>
public IEnumerable<string> RegisteredIndexes => _registeredIndexes;
public void Populate(params IIndexer[] indexes)
public void Populate(params IIndex[] indexes)
{
PopulateIndexes(indexes.Where(x => RegisteredIndexes.Contains(x.Name)));
}
protected abstract void PopulateIndexes(IEnumerable<IIndexer> indexes);
protected abstract void PopulateIndexes(IEnumerable<IIndex> indexes);
}
}
}

View File

@@ -42,7 +42,7 @@ namespace Umbraco.Examine
RegisterIndex(Constants.UmbracoIndexes.ExternalIndexName);
}
protected override void PopulateIndexes(IEnumerable<IIndexer> indexes)
protected override void PopulateIndexes(IEnumerable<IIndex> indexes)
{
const int pageSize = 10000;
var pageIndex = 0;

View File

@@ -28,9 +28,9 @@ namespace Umbraco.Examine
foreach (var m in media)
{
var urlValue = m.GetUrlSegment(_urlSegmentProviders);
var values = new Dictionary<string, object[]>
var values = new Dictionary<string, IEnumerable<object>>
{
{"icon", new object[] {m.ContentType.Icon}},
{"icon", m.ContentType.Icon.Yield()},
{"id", new object[] {m.Id}},
{"key", new object[] {m.Key}},
{"parentID", new object[] {m.Level > 1 ? m.ParentId : -1}},
@@ -39,11 +39,11 @@ namespace Umbraco.Examine
{"sortOrder", new object[] {m.SortOrder}},
{"createDate", new object[] {m.CreateDate}},
{"updateDate", new object[] {m.UpdateDate}},
{"nodeName", new object[] {m.Name}},
{"urlName", new object[] {urlValue}},
{"path", new object[] {m.Path}},
{"nodeName", m.Name.Yield()},
{"urlName", urlValue.Yield()},
{"path", m.Path.Yield()},
{"nodeType", new object[] {m.ContentType.Id}},
{"creatorName", new object[] {m.GetCreatorProfile(_userService).Name}}
{"creatorName", m.GetCreatorProfile(_userService).Name.Yield()}
};
foreach (var property in m.Properties)

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Examine
RegisterIndex(Core.Constants.UmbracoIndexes.MembersIndexName);
}
protected override void PopulateIndexes(IEnumerable<IIndexer> indexes)
protected override void PopulateIndexes(IEnumerable<IIndex> indexes)
{
const int pageSize = 1000;
var pageIndex = 0;

View File

@@ -19,9 +19,9 @@ namespace Umbraco.Examine
{
foreach (var m in members)
{
var values = new Dictionary<string, object[]>
var values = new Dictionary<string, IEnumerable<object>>
{
{"icon", new object[] {m.ContentType.Icon}},
{"icon", m.ContentType.Icon.Yield()},
{"id", new object[] {m.Id}},
{"key", new object[] {m.Key}},
{"parentID", new object[] {m.Level > 1 ? m.ParentId : -1}},
@@ -30,11 +30,11 @@ namespace Umbraco.Examine
{"sortOrder", new object[] {m.SortOrder}},
{"createDate", new object[] {m.CreateDate}},
{"updateDate", new object[] {m.UpdateDate}},
{"nodeName", new object[] {m.Name}},
{"path", new object[] {m.Path}},
{"nodeName", m.Name.Yield()},
{"path", m.Path.Yield()},
{"nodeType", new object[] {m.ContentType.Id}},
{"loginName", new object[] {m.Username}},
{"email", new object[] {m.Email}},
{"loginName", m.Username.Yield()},
{"email", m.Email.Yield()},
};
foreach (var property in m.Properties)

View File

@@ -48,7 +48,7 @@
</ItemGroup>
<ItemGroup>
<!-- note: NuGet deals with transitive references now -->
<PackageReference Include="Examine" Version="1.0.0-beta034" />
<PackageReference Include="Examine" Version="1.0.0-beta036" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NPoco" Version="3.9.4" />
</ItemGroup>
@@ -84,6 +84,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UmbracoContentIndexer.cs" />
<Compile Include="ContentValueSetValidator.cs" />
<Compile Include="UmbracoExamineIndexDiagnostics.cs" />
<Compile Include="UmbracoExamineIndexer.cs" />
<Compile Include="UmbracoExamineSearcher.cs" />
<Compile Include="UmbracoMemberIndexer.cs" />

View File

@@ -153,7 +153,7 @@ namespace Umbraco.Examine
//need to queue a delete item for each one found
foreach (var r in results)
{
QueueIndexOperation(new IndexOperation(IndexItem.ForId(r.Id), IndexOperationType.Delete));
QueueIndexOperation(new IndexOperation(new ValueSet(r.Id, null), IndexOperationType.Delete));
}
base.DeleteFromIndex(nodeId);

View File

@@ -0,0 +1,70 @@
using System.Collections.Generic;
using Lucene.Net.Store;
using Umbraco.Core;
using Umbraco.Core.Logging;
namespace Umbraco.Examine
{
public class UmbracoExamineIndexDiagnostics : IIndexDiagnostics
{
private readonly UmbracoExamineIndexer _index;
private readonly ILogger _logger;
public UmbracoExamineIndexDiagnostics(UmbracoExamineIndexer index, ILogger logger)
{
_index = index;
_logger = logger;
}
public int DocumentCount
{
get
{
try
{
return _index.GetIndexDocumentCount();
}
catch (AlreadyClosedException)
{
_logger.Warn(typeof(UmbracoContentIndexer), "Cannot get GetIndexDocumentCount, the writer is already closed");
return 0;
}
}
}
public int FieldCount
{
get
{
try
{
return _index.GetIndexFieldCount();
}
catch (AlreadyClosedException)
{
_logger.Warn(typeof(UmbracoContentIndexer), "Cannot get GetIndexFieldCount, the writer is already closed");
return 0;
}
}
}
public Attempt<string> IsHealthy()
{
var isHealthy = _index.IsHealthy(out var indexError);
return isHealthy ? Attempt<string>.Succeed() : Attempt.Fail(indexError.Message);
}
public virtual IReadOnlyDictionary<string, object> Metadata => new Dictionary<string, object>
{
[nameof(UmbracoExamineIndexer.CommitCount)] = _index.CommitCount,
[nameof(UmbracoExamineIndexer.DefaultAnalyzer)] = _index.DefaultAnalyzer.GetType(),
[nameof(UmbracoExamineIndexer.DirectoryFactory)] = _index.DirectoryFactory,
[nameof(UmbracoExamineIndexer.EnableDefaultEventHandler)] = _index.EnableDefaultEventHandler,
[nameof(UmbracoExamineIndexer.LuceneIndexFolder)] = _index.LuceneIndexFolder?.ToString(),
[nameof(UmbracoExamineIndexer.SupportSoftDelete)] = _index.SupportSoftDelete,
[nameof(UmbracoExamineIndexer.FieldDefinitionCollection)] = _index.FieldDefinitionCollection,
[nameof(UmbracoExamineIndexer.FieldValueTypeCollection)] = _index.FieldValueTypeCollection,
};
}
}

View File

@@ -25,7 +25,7 @@ namespace Umbraco.Examine
/// An abstract provider containing the basic functionality to be able to query against
/// Umbraco data.
/// </summary>
public abstract class UmbracoExamineIndexer : LuceneIndexer, IUmbracoIndexer, IIndexDiagnostics
public abstract class UmbracoExamineIndexer : LuceneIndex, IUmbracoIndexer, IIndexDiagnostics
{
// note
// wrapping all operations that end up calling base.SafelyProcessQueueItems in a safe call
@@ -82,6 +82,8 @@ namespace Umbraco.Examine
//try to set the value of `LuceneIndexFolder` for diagnostic reasons
if (luceneDirectory is FSDirectory fsDir)
LuceneIndexFolder = fsDir.Directory;
_diagnostics = new UmbracoExamineIndexDiagnostics(this, ProfilingLogger.Logger);
}
private readonly bool _configBased = false;
@@ -315,15 +317,15 @@ namespace Umbraco.Examine
/// <summary>
/// Overridden for logging.
/// </summary>
protected override void AddDocument(Document doc, IndexItem item, IndexWriter writer)
protected override void AddDocument(Document doc, ValueSet valueSet, IndexWriter writer)
{
ProfilingLogger.Logger.Debug(GetType(),
"Write lucene doc id:{DocumentId}, category:{DocumentCategory}, type:{DocumentItemType}",
item.ValueSet.Id,
item.ValueSet.Category,
item.ValueSet.ItemType);
valueSet.Id,
valueSet.Category,
valueSet.ItemType);
base.AddDocument(doc, item, writer);
base.AddDocument(doc, valueSet, writer);
}
protected override void OnTransformingIndexValues(IndexingItemEventArgs e)
@@ -331,16 +333,16 @@ namespace Umbraco.Examine
base.OnTransformingIndexValues(e);
//ensure special __Path field
var path = e.IndexItem.ValueSet.GetValue("path");
var path = e.ValueSet.GetValue("path");
if (path != null)
{
e.IndexItem.ValueSet.Set(IndexPathFieldName, path);
e.ValueSet.Set(IndexPathFieldName, path);
}
//icon
if (e.IndexItem.ValueSet.Values.TryGetValue("icon", out var icon) && e.IndexItem.ValueSet.Values.ContainsKey(IconFieldName) == false)
if (e.ValueSet.Values.TryGetValue("icon", out var icon) && e.ValueSet.Values.ContainsKey(IconFieldName) == false)
{
e.IndexItem.ValueSet.Values[IconFieldName] = icon;
e.ValueSet.Values[IconFieldName] = icon;
}
}
@@ -356,53 +358,12 @@ namespace Umbraco.Examine
#region IIndexDiagnostics
public int DocumentCount
{
get
{
try
{
return this.GetIndexDocumentCount();
}
catch (AlreadyClosedException)
{
ProfilingLogger.Logger.Warn(typeof(UmbracoContentIndexer), "Cannot get GetIndexDocumentCount, the writer is already closed");
return 0;
}
}
}
private readonly UmbracoExamineIndexDiagnostics _diagnostics;
public int FieldCount
{
get
{
try
{
return this.GetIndexFieldCount();
}
catch (AlreadyClosedException)
{
ProfilingLogger.Logger.Warn(typeof(UmbracoContentIndexer), "Cannot get GetIndexFieldCount, the writer is already closed");
return 0;
}
}
}
public Attempt<string> IsHealthy()
{
var isHealthy = this.IsHealthy(out var indexError);
return isHealthy ? Attempt<string>.Succeed() : Attempt.Fail(indexError.Message);
}
public virtual IReadOnlyDictionary<string, object> Metadata => new Dictionary<string, object>
{
[nameof(CommitCount)] = CommitCount,
[nameof(DefaultAnalyzer)] = DefaultAnalyzer.GetType(),
[nameof(DirectoryFactory)] = DirectoryFactory,
[nameof(EnableDefaultEventHandler)] = EnableDefaultEventHandler,
[nameof(LuceneIndexFolder)] = LuceneIndexFolder?.ToString(),
[nameof(SupportSoftDelete)] = SupportSoftDelete
};
public int DocumentCount => _diagnostics.DocumentCount;
public int FieldCount => _diagnostics.FieldCount;
public Attempt<string> IsHealthy() => _diagnostics.IsHealthy();
public virtual IReadOnlyDictionary<string, object> Metadata => _diagnostics.Metadata;
#endregion
}

View File

@@ -137,7 +137,7 @@ namespace Umbraco.Examine
var fields = base.GetAllIndexedFields();
return fields
.Where(x => x != UmbracoExamineIndexer.IndexPathFieldName)
.Where(x => x != LuceneIndexer.ItemTypeFieldName)
.Where(x => x != LuceneIndex.ItemTypeFieldName)
.ToArray();
}

View File

@@ -80,10 +80,10 @@ namespace Umbraco.Examine
{
base.OnTransformingIndexValues(e);
if (e.IndexItem.ValueSet.Values.TryGetValue("key", out var key) && e.IndexItem.ValueSet.Values.ContainsKey("__key") == false)
if (e.ValueSet.Values.TryGetValue("key", out var key) && e.ValueSet.Values.ContainsKey("__key") == false)
{
//double __ prefix means it will be indexed as culture invariant
e.IndexItem.ValueSet.Values["__key"] = key;
e.ValueSet.Values["__key"] = key;
}
}

View File

@@ -6,10 +6,10 @@ namespace Umbraco.Tests.TestHelpers.Stubs
{
internal class TestExamineManager : IExamineManager
{
private readonly ConcurrentDictionary<string, IIndexer> _indexers = new ConcurrentDictionary<string, IIndexer>();
private readonly ConcurrentDictionary<string, IIndex> _indexers = new ConcurrentDictionary<string, IIndex>();
private readonly ConcurrentDictionary<string, ISearcher> _searchers = new ConcurrentDictionary<string, ISearcher>();
public void AddIndexer(IIndexer indexer)
public void AddIndex(IIndex indexer)
{
_indexers.TryAdd(indexer.Name, indexer);
}
@@ -24,7 +24,7 @@ namespace Umbraco.Tests.TestHelpers.Stubs
//noop
}
public IIndexer GetIndexer(string indexerName)
public IIndex GetIndex(string indexerName)
{
return _indexers.TryGetValue(indexerName, out var indexer) ? indexer : null;
}
@@ -34,6 +34,6 @@ namespace Umbraco.Tests.TestHelpers.Stubs
return _searchers.TryGetValue(searcherName, out var indexer) ? indexer : null;
}
public IReadOnlyDictionary<string, IIndexer> IndexProviders => _indexers;
public IReadOnlyDictionary<string, IIndex> IndexProviders => _indexers;
}
}

View File

@@ -77,7 +77,7 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="7.0.1" />
<PackageReference Include="Castle.Core" Version="4.2.1" />
<PackageReference Include="Examine" Version="1.0.0-beta034" />
<PackageReference Include="Examine" Version="1.0.0-beta036" />
<PackageReference Include="HtmlAgilityPack">
<Version>1.8.9</Version>
</PackageReference>

View File

@@ -167,12 +167,12 @@ namespace Umbraco.Tests.UmbracoExamine
var protectedQuery = new BooleanQuery();
protectedQuery.Add(
new BooleanClause(
new TermQuery(new Term(LuceneIndexer.CategoryFieldName, IndexTypes.Content)),
new TermQuery(new Term(LuceneIndex.CategoryFieldName, IndexTypes.Content)),
Occur.MUST));
protectedQuery.Add(
new BooleanClause(
new TermQuery(new Term(LuceneIndexer.ItemIdFieldName, ExamineDemoDataContentService.ProtectedNode.ToString())),
new TermQuery(new Term(LuceneIndex.ItemIdFieldName, ExamineDemoDataContentService.ProtectedNode.ToString())),
Occur.MUST));
var collector = TopScoreDocCollector.Create(100, true);
@@ -293,7 +293,7 @@ namespace Umbraco.Tests.UmbracoExamine
//create the whole thing
rebuilder.Populate(indexer);
var result = searcher.Search(searcher.CreateCriteria().Field(LuceneIndexer.CategoryFieldName, IndexTypes.Content).Compile());
var result = searcher.Search(searcher.CreateCriteria().Field(LuceneIndex.CategoryFieldName, IndexTypes.Content).Compile());
Assert.AreEqual(21, result.TotalItemCount);
//delete all content
@@ -304,13 +304,13 @@ namespace Umbraco.Tests.UmbracoExamine
//ensure it's all gone
result = searcher.Search(searcher.CreateCriteria().Field(LuceneIndexer.CategoryFieldName, IndexTypes.Content).Compile());
result = searcher.Search(searcher.CreateCriteria().Field(LuceneIndex.CategoryFieldName, IndexTypes.Content).Compile());
Assert.AreEqual(0, result.TotalItemCount);
//call our indexing methods
rebuilder.Populate(indexer);
result = searcher.Search(searcher.CreateCriteria().Field(LuceneIndexer.CategoryFieldName, IndexTypes.Content).Compile());
result = searcher.Search(searcher.CreateCriteria().Field(LuceneIndex.CategoryFieldName, IndexTypes.Content).Compile());
Assert.AreEqual(21, result.TotalItemCount);
}
}

View File

@@ -1,14 +0,0 @@
<h3>Start here</h3>
<h4>This section contains the tools to add advanced features to your Umbraco site</h4>
<p>From here you can explore and install packages, create macros, add data types, and much more. Start by exploring the below links or videos.</p>
<h4>Find out more:</h4>
<ul>
<li>Find the answers to your Umbraco questions in our <a class="btn-link -underline href="https://our.umbraco.com/documentation/" target="_blank">Documentation</a></li>
<li>Ask a question in the <a class="btn-link -underline href="https://our.umbraco.com/" target="_blank">Community Forum</a></li>
<li>Find an add-on <a class="btn-link -underline href="https://our.umbraco.com/projects" target="_blank">package</a> to help you get going quickly</li>
<li>Watch our <a class="btn-link -underline href="https://umbraco.tv" target="_blank">tutorial videos</a> (some are free, some require a subscription)</li>
<li>Find out about our <a class="btn-link -underline href="https://umbraco.com/products" target="_blank">productivity boosting tools and commercial support</a></li>
<li>Find out about real-life <a class="btn-link -underline href="https://umbraco.com/training/" target="_blank">training and certification</a> opportunities</li>
</ul>

View File

@@ -28,124 +28,48 @@
<div class="umb-healthcheck-group__details-status" ng-repeat="indexer in indexerDetails">
<div class="umb-healthcheck-group__details-status-icon-container">
<i class="umb-healthcheck-status-icon" ng-class="{'icon-check color-green' : indexer.isHealthy, 'icon-delete color-red' : !indexer.isHealthy}"></i>
<i class="umb-healthcheck-status-icon"
ng-class="{'icon-check color-green' : indexer.isHealthy, 'icon-delete color-red' : !indexer.isHealthy}"></i>
</div>
<div class="umb-healthcheck-group__details-status-content">
<div class="umb-healthcheck-group__details-status-text">
<div ng-show="!indexer.isHealthy">
{{indexer.name}}
</div>
<a class="btn-link -underline" href="" ng-click="toggle(indexer, 'showProperties')" ng-show="indexer.isHealthy">
{{indexer.name}}
</a>
<div ng-if="!indexer.isHealthy" class="text-error">
<div ng-show="!indexer.isHealthy" class="color-red">
The index cannot be read and will need to be rebuilt
</div>
<a class="btn-link -underline" href="" ng-click="toggle(indexer, 'showProperties')">
{{indexer.name}}
</a>
</div>
<div class="umb-healthcheck-group__details-status-actions" ng-if="!indexer.isHealthy">
<div class="umb-healthcheck-group__details-status-action">
<umb-button
ng-if="!indexer.isProcessing && (!indexer.processingAttempts || indexer.processingAttempts < 100)"
type="button"
button-style="success"
action="rebuildIndex(indexer)"
label="Rebuild index">
</umb-button>
</div>
</div>
<div class="umb-healthcheck-group__details-status-actions" ng-show="indexer.isHealthy && indexer.showProperties">
<div class="umb-healthcheck-group__details-status-actions" ng-show="indexer.showProperties">
<ul>
<li>
<a href="" ng-click="toggle(indexer, 'showTools')">Index info & tools</a>
<div ng-show="indexer.showTools && indexer.isLuceneIndex">
<div ng-show="indexer.showTools">
<div>
<br />
<div ng-show="!indexer.isProcessing && (!indexer.processingAttempts || indexer.processingAttempts < 100)"
class="umb-healthcheck-group__details-status-action">
<umb-button type="button" button-style="success" action="rebuildIndex(indexer)" label="Rebuild index"></umb-button>
<div class="umb-healthcheck-group__details-status-action">
<umb-button ng-show="!indexer.isProcessing && (!indexer.processingAttempts || indexer.processingAttempts < 100)"
type="button"
button-style="success"
action="rebuildIndex(indexer)"
label="Rebuild index">
</umb-button>
</div>
<div ng-show="indexer.processingAttempts >= 100">
The process is taking longer than expected, check the umbraco log to see if there have been any errors during this operation
</div>
</div>
<table class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr>
<th>Documents in index</th>
<td>{{indexer.documentCount}}</td>
</tr>
<tr>
<th>Fields in index</th>
<td>{{indexer.fieldCount}}</td>
</tr>
</table>
</div>
</li>
<li ng-show="indexer.indexCriteria.IncludeNodeTypes.length > 0 || indexer.indexCriteria.ExcludeNodeTypes.length > 0 || indexer.indexCriteria.ParentNodeId">
<a href="" ng-click="toggle(indexer, 'showNodeTypes')">Node types</a>
<table ng-show="indexer.showNodeTypes" class="table table-bordered table-condensed">
<tr ng-show="indexer.indexCriteria.IncludeNodeTypes.length > 0">
<th>Include node types</th>
<td>{{indexer.indexCriteria.IncludeNodeTypes | json}}</td>
</tr>
<tr ng-show="indexer.indexCriteria.ExcludeNodeTypes.length > 0">
<th>Exclude node types</th>
<td>{{indexer.indexCriteria.ExcludeNodeTypes | json}}</td>
</tr>
<tr ng-show="indexer.indexCriteria.ParentNodeId">
<th>Parent node id</th>
<td>{{indexer.indexCriteria.ParentNodeId}}</td>
</tr>
</table>
</li>
<li ng-show="indexer.indexCriteria.StandardFields.length > 0">
<a href="" ng-click="toggle(indexer, 'showSystemFields')">System fields</a>
<table ng-show="indexer.showSystemFields" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<thead>
<tr>
<th>Name</th>
<th>Enable sorting</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="field in indexer.indexCriteria.StandardFields">
<th>{{field.Name}}</th>
<td>{{field.EnableSorting}}</td>
<td>{{field.Type}}</td>
</tr>
</tbody>
</table>
</li>
<li ng-show="indexer.indexCriteria.UserFields.length > 0">
<a href="" ng-click="toggle(indexer, 'showUserFields')">User fields</a>
<table ng-show="indexer.showUserFields" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<thead>
<tr>
<th>Name</th>
<th>Enable sorting</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="field in indexer.indexCriteria.UserFields">
<th>{{field.Name}}</th>
<td>{{field.EnableSorting}}</td>
<td>{{field.Type}}</td>
</tr>
</tbody>
</table>
</li>
<li>
<a href="" ng-click="toggle(indexer, 'showProviderProperties')">Provider properties</a>
<a href="" ng-click="toggle(indexer, 'showProviderProperties')">Index properties</a>
<table ng-show="indexer.showProviderProperties" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr ng-repeat="(key, val) in indexer.providerProperties track by $index">

View File

@@ -88,7 +88,7 @@
<PackageReference Include="CSharpTest.Net.Collections" Version="14.906.1403.1082" />
<PackageReference Include="ClientDependency" Version="1.9.7" />
<PackageReference Include="ClientDependency-Mvc5" Version="1.8.0.0" />
<PackageReference Include="Examine" Version="1.0.0-beta034" />
<PackageReference Include="Examine" Version="1.0.0-beta036" />
<PackageReference Include="ImageProcessor.Web" Version="4.9.3.25" />
<PackageReference Include="ImageProcessor.Web.Config" Version="2.4.1.19" />
<PackageReference Include="Lucene.Net.Contrib" Version="3.0.3" />

View File

@@ -121,7 +121,7 @@ namespace Umbraco.Web.Editors
/// </remarks>
public ExamineIndexModel PostCheckRebuildIndex(string indexerName)
{
var msg = ValidateLuceneIndexer(indexerName, out LuceneIndexer indexer);
var msg = ValidateLuceneIndexer(indexerName, out LuceneIndex indexer);
if (msg.IsSuccessStatusCode)
{
var cacheKey = "temp_indexing_op_" + indexerName;
@@ -130,7 +130,7 @@ namespace Umbraco.Web.Editors
//if its still there then it's not done
return found != null
? null
: CreateModel(new KeyValuePair<string, IIndexer>(indexerName, indexer));
: CreateModel(new KeyValuePair<string, IIndex>(indexerName, indexer));
}
throw new HttpResponseException(msg);
@@ -143,7 +143,7 @@ namespace Umbraco.Web.Editors
/// <returns></returns>
public HttpResponseMessage PostRebuildIndex(string indexerName)
{
var msg = ValidateLuceneIndexer(indexerName, out LuceneIndexer indexer);
var msg = ValidateLuceneIndexer(indexerName, out LuceneIndex indexer);
if (msg.IsSuccessStatusCode)
{
_logger.Info<ExamineManagementController>("Rebuilding index '{IndexerName}'", indexerName);
@@ -185,7 +185,7 @@ namespace Umbraco.Web.Editors
private ExamineIndexModel CreateModel(KeyValuePair<string, IIndexer> indexerKeyVal)
private ExamineIndexModel CreateModel(KeyValuePair<string, IIndex> indexerKeyVal)
{
var indexer = indexerKeyVal.Value;
var indexName = indexerKeyVal.Key;
@@ -249,7 +249,7 @@ namespace Umbraco.Web.Editors
}
private HttpResponseMessage ValidateLuceneIndexer<T>(string indexerName, out T indexer)
where T : class, IIndexer
where T : class, IIndex
{
indexer = null;
@@ -270,7 +270,7 @@ namespace Umbraco.Web.Editors
//static listener so it's not GC'd
private void Indexer_IndexOperationComplete(object sender, EventArgs e)
{
var indexer = (LuceneIndexer) sender;
var indexer = (LuceneIndex) sender;
//ensure it's not listening anymore
indexer.IndexOperationComplete -= Indexer_IndexOperationComplete;

View File

@@ -1,212 +0,0 @@
// fixme - Examine is borked
// this cannot compile because it seems to require some changes that are not in Examine v2
// this should *not* exist, see ExamineComponent instead, which handles everything about Examine
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using Examine;
//using Examine.Config;
//using Examine.LuceneEngine;
//using Examine.LuceneEngine.Providers;
//using Examine.Providers;
//using Lucene.Net.Index;
//using Lucene.Net.Store;
//using Umbraco.Core;
//using Umbraco.Core.Logging;
//using UmbracoExamine;
//namespace Umbraco.Web
//{
// /// <summary>
// /// Used to configure Examine during startup for the web application
// /// </summary>
// internal class ExamineStartup
// {
// private readonly List<BaseIndexProvider> _indexesToRebuild = new List<BaseIndexProvider>();
// private readonly ApplicationContext _appCtx;
// private readonly ProfilingLogger _profilingLogger;
// private static bool _isConfigured = false;
// //this is used if we are not the MainDom, in which case we need to ensure that if indexes need rebuilding that this
// //doesn't occur since that should only occur when we are MainDom
// private bool _disableExamineIndexing = false;
// public ExamineStartup(ApplicationContext appCtx)
// {
// _appCtx = appCtx;
// _profilingLogger = appCtx.ProfilingLogger;
// }
// /// <summary>
// /// Called during the initialize operation of the boot manager process
// /// </summary>
// public void Initialize()
// {
// //We want to manage Examine's appdomain shutdown sequence ourselves so first we'll disable Examine's default behavior
// //and then we'll use MainDom to control Examine's shutdown
// ExamineManager.DisableDefaultHostingEnvironmentRegistration();
// //we want to tell examine to use a different fs lock instead of the default NativeFSFileLock which could cause problems if the appdomain
// //terminates and in some rare cases would only allow unlocking of the file if IIS is forcefully terminated. Instead we'll rely on the simplefslock
// //which simply checks the existence of the lock file
// DirectoryTracker.DefaultLockFactory = d =>
// {
// var simpleFsLockFactory = new NoPrefixSimpleFsLockFactory(d);
// return simpleFsLockFactory;
// };
// //This is basically a hack for this item: http://issues.umbraco.org/issue/U4-5976
// // when Examine initializes it will try to rebuild if the indexes are empty, however in many cases not all of Examine's
// // event handlers will be assigned during bootup when the rebuilding starts which is a problem. So with the examine 0.1.58.2941 build
// // it has an event we can subscribe to in order to cancel this rebuilding process, but what we'll do is cancel it and postpone the rebuilding until the
// // boot process has completed. It's a hack but it works.
// ExamineManager.Instance.BuildingEmptyIndexOnStartup += OnInstanceOnBuildingEmptyIndexOnStartup;
// //let's deal with shutting down Examine with MainDom
// var examineShutdownRegistered = _appCtx.MainDom.Register(() =>
// {
// using (_profilingLogger.TraceDuration<ExamineStartup>("Examine shutting down"))
// {
// //Due to the way Examine's own IRegisteredObject works, we'll first run it with immediate=false and then true so that
// //it's correct subroutines are executed (otherwise we'd have to run this logic manually ourselves)
// ExamineManager.Instance.Stop(false);
// ExamineManager.Instance.Stop(true);
// }
// });
// if (examineShutdownRegistered)
// {
// _profilingLogger.Logger.Debug<ExamineStartup>("Examine shutdown registered with MainDom");
// }
// else
// {
// _profilingLogger.Logger.Debug<ExamineStartup>("Examine shutdown not registered, this appdomain is not the MainDom");
// //if we could not register the shutdown examine ourselves, it means we are not maindom! in this case all of examine should be disabled
// //from indexing anything on startup!!
// _disableExamineIndexing = true;
// Suspendable.ExamineEvents.SuspendIndexers();
// }
// }
// /// <summary>
// /// Called during the Complete operation of the boot manager process
// /// </summary>
// public void Complete()
// {
// EnsureUnlockedAndConfigured();
// //Ok, now that everything is complete we'll check if we've stored any references to index that need rebuilding and run them
// // (see the initialize method for notes) - we'll ensure we remove the event handler too in case examine manager doesn't actually
// // initialize during startup, in which case we want it to rebuild the indexes itself.
// ExamineManager.Instance.BuildingEmptyIndexOnStartup -= OnInstanceOnBuildingEmptyIndexOnStartup;
// //don't do anything if we have disabled this
// if (_disableExamineIndexing == false)
// {
// foreach (var indexer in _indexesToRebuild)
// {
// indexer.RebuildIndex();
// }
// }
// }
// /// <summary>
// /// Called to perform the rebuilding indexes on startup if the indexes don't exist
// /// </summary>
// public void RebuildIndexes()
// {
// //don't do anything if we have disabled this
// if (_disableExamineIndexing) return;
// EnsureUnlockedAndConfigured();
// //If the developer has explicitly opted out of rebuilding indexes on startup then we
// // should adhere to that and not do it, this means that if they are load balancing things will be
// // out of sync if they are auto-scaling but there's not much we can do about that.
// if (ExamineSettings.Instance.RebuildOnAppStart == false) return;
// foreach (var indexer in GetIndexesForColdBoot())
// {
// indexer.RebuildIndex();
// }
// }
// /// <summary>
// /// The method used to create indexes on a cold boot
// /// </summary>
// /// <remarks>
// /// A cold boot is when the server determines it will not (or cannot) process instructions in the cache table and
// /// will rebuild it's own caches itself.
// /// </remarks>
// public IEnumerable<BaseIndexProvider> GetIndexesForColdBoot()
// {
// // NOTE: This is IMPORTANT! ... we don't want to rebuild any index that is already flagged to be re-indexed
// // on startup based on our _indexesToRebuild variable and how Examine auto-rebuilds when indexes are empty.
// // This callback is used above for the DatabaseServerMessenger startup options.
// // all indexes
// IEnumerable<BaseIndexProvider> indexes = ExamineManager.Instance.IndexProviderCollection;
// // except those that are already flagged
// // and are processed in Complete()
// if (_indexesToRebuild.Any())
// indexes = indexes.Except(_indexesToRebuild);
// // return
// foreach (var index in indexes)
// yield return index;
// }
// /// <summary>
// /// Must be called to configure each index and ensure it's unlocked before any indexing occurs
// /// </summary>
// /// <remarks>
// /// Indexing rebuilding can occur on a normal boot if the indexes are empty or on a cold boot by the database server messenger. Before
// /// either of these happens, we need to configure the indexes.
// /// </remarks>
// private void EnsureUnlockedAndConfigured()
// {
// if (_isConfigured) return;
// _isConfigured = true;
// foreach (var luceneIndexer in ExamineManager.Instance.IndexProviderCollection.OfType<LuceneIndexer>())
// {
// //We now need to disable waiting for indexing for Examine so that the appdomain is shutdown immediately and doesn't wait for pending
// //indexing operations. We used to wait for indexing operations to complete but this can cause more problems than that is worth because
// //that could end up halting shutdown for a very long time causing overlapping appdomains and many other problems.
// luceneIndexer.WaitForIndexQueueOnShutdown = false;
// //we should check if the index is locked ... it shouldn't be! We are using simple fs lock now and we are also ensuring that
// //the indexes are not operational unless MainDom is true so if _disableExamineIndexing is false then we should be in charge
// if (_disableExamineIndexing == false)
// {
// var dir = luceneIndexer.GetLuceneDirectory();
// if (IndexWriter.IsLocked(dir))
// {
// _profilingLogger.Logger.Info<ExamineStartup>("Forcing index " + luceneIndexer.IndexSetName + " to be unlocked since it was left in a locked state");
// IndexWriter.Unlock(dir);
// }
// }
// }
// }
// private void OnInstanceOnBuildingEmptyIndexOnStartup(object sender, BuildingEmptyIndexOnStartupEventArgs args)
// {
// //store the indexer that needs rebuilding because it's empty for when the boot process
// // is complete and cancel this current event so the rebuild process doesn't start right now.
// args.Cancel = true;
// _indexesToRebuild.Add((BaseIndexProvider)args.Indexer);
// //check if the index is rebuilding due to an error and log it
// if (args.IsHealthy == false)
// {
// var baseIndex = args.Indexer as BaseIndexProvider;
// var name = baseIndex != null ? baseIndex.Name : "[UKNOWN]";
// _profilingLogger.Logger.Error<ExamineStartup>(string.Format("The index {0} is rebuilding due to being unreadable/corrupt", name), args.UnhealthyException);
// }
// }
// }
//}

View File

@@ -136,9 +136,9 @@ namespace Umbraco.Web.Models.Mapping
dest.Key = key;
//need to set the UDI
if (src.Values.ContainsKey(LuceneIndexer.CategoryFieldName))
if (src.Values.ContainsKey(LuceneIndex.CategoryFieldName))
{
switch (src.Values[LuceneIndexer.CategoryFieldName])
switch (src.Values[LuceneIndex.CategoryFieldName])
{
case IndexTypes.Member:
dest.Udi = new GuidUdi(Constants.UdiEntityType.Member, dest.Key);
@@ -168,9 +168,9 @@ namespace Umbraco.Web.Models.Mapping
}
dest.Path = src.Values.ContainsKey(UmbracoExamineIndexer.IndexPathFieldName) ? src.Values[UmbracoExamineIndexer.IndexPathFieldName] : "";
if (src.Values.ContainsKey(LuceneIndexer.ItemTypeFieldName))
if (src.Values.ContainsKey(LuceneIndex.ItemTypeFieldName))
{
dest.AdditionalData.Add("contentType", src.Values[LuceneIndexer.ItemTypeFieldName]);
dest.AdditionalData.Add("contentType", src.Values[LuceneIndex.ItemTypeFieldName]);
}
});

View File

@@ -57,7 +57,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
ValidateAndSetProperty(valueDictionary, val => _sortOrder = Int32.Parse(val), "sortOrder");
ValidateAndSetProperty(valueDictionary, val => _name = val, "nodeName", "__nodeName");
ValidateAndSetProperty(valueDictionary, val => _urlName = val, "urlName");
ValidateAndSetProperty(valueDictionary, val => _documentTypeAlias = val, "nodeTypeAlias", LuceneIndexer.ItemTypeFieldName);
ValidateAndSetProperty(valueDictionary, val => _documentTypeAlias = val, "nodeTypeAlias", LuceneIndex.ItemTypeFieldName);
ValidateAndSetProperty(valueDictionary, val => _documentTypeId = Int32.Parse(val), "nodeType");
//ValidateAndSetProperty(valueDictionary, val => _writerName = val, "writerName");
ValidateAndSetProperty(valueDictionary, val => _creatorName = val, "creatorName", "writerName"); //this is a bit of a hack fix for: U4-1132

View File

@@ -38,7 +38,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// method GetExamineManagerSafe().
//
private readonly ISearcher _searchProvider;
private readonly IIndexer _indexProvider;
private readonly IIndex _indexProvider;
private readonly XmlStore _xmlStore;
private readonly PublishedContentTypeCache _contentTypeCache;

View File

@@ -234,8 +234,8 @@ namespace Umbraco.Web
if (_query != null) return _query.Search(skip, take, out totalRecords, term, useWildCards, indexName);
var indexer = string.IsNullOrEmpty(indexName)
? Examine.ExamineManager.Instance.GetIndexer(Constants.Examine.ExternalIndexer)
: Examine.ExamineManager.Instance.GetIndexer(indexName);
? Examine.ExamineManager.Instance.GetIndex(Constants.Examine.ExternalIndexer)
: Examine.ExamineManager.Instance.GetIndex(indexName);
if (indexer == null) throw new InvalidOperationException("No index found by name " + indexName);
@@ -278,7 +278,7 @@ namespace Umbraco.Web
/// <summary>
/// Creates an ISearchCriteria for searching all fields in a <see cref="BaseLuceneSearcher"/>.
/// </summary>
private ISearchCriteria SearchAllFields(string searchText, bool useWildcards, Examine.ISearcher searcher, Examine.IIndexer indexer)
private ISearchCriteria SearchAllFields(string searchText, bool useWildcards, Examine.ISearcher searcher, Examine.IIndex indexer)
{
var sc = searcher.CreateCriteria();

View File

@@ -113,7 +113,7 @@ namespace Umbraco.Web.Search
//create the indexes and register them with the manager
foreach(var index in indexBuilder.Create())
{
_examineManager.AddIndexer(index);
_examineManager.AddIndex(index);
}
profilingLogger.Logger.Debug<ExamineComponent>("Examine shutdown registered with MainDom");
@@ -192,7 +192,7 @@ namespace Umbraco.Web.Search
_isConfigured = true;
foreach (var luceneIndexer in examineManager.IndexProviders.Values.OfType<LuceneIndexer>())
foreach (var luceneIndexer in examineManager.IndexProviders.Values.OfType<LuceneIndex>())
{
//We now need to disable waiting for indexing for Examine so that the appdomain is shutdown immediately and doesn't wait for pending
//indexing operations. We used to wait for indexing operations to complete but this can cause more problems than that is worth because

View File

@@ -14,6 +14,9 @@ namespace Umbraco.Web.Search
[DataMember(Name = "healthStatus")]
public string HealthStatus { get; set; }
[DataMember(Name = "isHealthy")]
public bool IsHealthy => false;
[DataMember(Name = "providerProperties")]
public IReadOnlyDictionary<string, object> ProviderProperties { get; set; }

View File

@@ -13,10 +13,10 @@ namespace Umbraco.Web.Search
/// </summary>
public class GenericIndexDiagnostics : IIndexDiagnostics
{
private readonly IIndexer _index;
private readonly IIndex _index;
private static readonly string[] IgnoreProperties = { "Description" };
public GenericIndexDiagnostics(IIndexer index)
public GenericIndexDiagnostics(IIndex index)
{
_index = index;
}

View File

@@ -5,6 +5,6 @@ namespace Umbraco.Web.Search
{
internal interface IUmbracoIndexesBuilder
{
IEnumerable<IIndexer> Create();
IEnumerable<IIndex> Create();
}
}

View File

@@ -45,7 +45,7 @@ namespace Umbraco.Web.Search
/// Creates the Umbraco indexes
/// </summary>
/// <returns></returns>
public IEnumerable<IIndexer> Create()
public IEnumerable<IIndex> Create()
{
return new []
{
@@ -55,7 +55,7 @@ namespace Umbraco.Web.Search
};
}
private IIndexer CreateInternalIndex()
private IIndex CreateInternalIndex()
{
var index = new UmbracoContentIndexer(
Constants.UmbracoIndexes.InternalIndexName,
@@ -69,7 +69,7 @@ namespace Umbraco.Web.Search
return index;
}
private IIndexer CreateExternalIndex()
private IIndex CreateExternalIndex()
{
var index = new UmbracoContentIndexer(
Constants.UmbracoIndexes.ExternalIndexName,
@@ -83,7 +83,7 @@ namespace Umbraco.Web.Search
return index;
}
private IIndexer CreateMemberIndex()
private IIndex CreateMemberIndex()
{
var index = new UmbracoMemberIndexer(
Constants.UmbracoIndexes.MembersIndexName,

View File

@@ -62,7 +62,7 @@
<PackageReference Include="AutoMapper" Version="7.0.1" />
<PackageReference Include="ClientDependency" Version="1.9.7" />
<PackageReference Include="CSharpTest.Net.Collections" Version="14.906.1403.1082" />
<PackageReference Include="Examine" Version="1.0.0-beta034" />
<PackageReference Include="Examine" Version="1.0.0-beta036" />
<PackageReference Include="HtmlAgilityPack" Version="1.8.9" />
<PackageReference Include="ImageProcessor">
<Version>2.6.2.25</Version>
@@ -219,7 +219,6 @@
<Compile Include="Editors\UserGroupsController.cs" />
<Compile Include="Editors\Filters\UserGroupValidateAttribute.cs" />
<Compile Include="Editors\UsersController.cs" />
<Compile Include="ExamineStartup.cs" />
<Compile Include="Features\DisabledFeatures.cs" />
<Compile Include="Features\EnabledFeatures.cs" />
<Compile Include="Features\UmbracoFeatures.cs" />