Gets both media and member indexing working for when media/member types are changed
This commit is contained in:
@@ -137,11 +137,28 @@ namespace Umbraco.Core.Services
|
||||
IQuery<IMedia> filter, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by the Id of the <see cref="IContentType"/>
|
||||
/// Gets paged documents of a content content
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="IMediaType"/></param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
IEnumerable<IMedia> GetMediaOfMediaType(int id);
|
||||
/// <param name="contentTypeId">The page number.</param>
|
||||
/// <param name="pageIndex">The page number.</param>
|
||||
/// <param name="pageSize">The page size.</param>
|
||||
/// <param name="totalRecords">Total number of documents.</param>
|
||||
/// <param name="filter">Search text filter.</param>
|
||||
/// <param name="ordering">Ordering infos.</param>
|
||||
IEnumerable<IMedia> GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IMedia> filter, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged documents for specified content types
|
||||
/// </summary>
|
||||
/// <param name="contentTypeIds">The page number.</param>
|
||||
/// <param name="pageIndex">The page number.</param>
|
||||
/// <param name="pageSize">The page size.</param>
|
||||
/// <param name="totalRecords">Total number of documents.</param>
|
||||
/// <param name="filter">Search text filter.</param>
|
||||
/// <param name="ordering">Ordering infos.</param>
|
||||
IEnumerable<IMedia> GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IMedia> filter, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects, which reside at the first level / root
|
||||
|
||||
@@ -364,18 +364,39 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by the Id of the <see cref="IMediaType"/>
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="IMediaType"/></param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetMediaOfMediaType(int id)
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IMedia> GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords, IQuery<IMedia> filter, Ordering ordering = null)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("sortOrder");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
var query = Query<IMedia>().Where(x => x.ContentTypeId == id);
|
||||
return _mediaRepository.Get(query);
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
return _mediaRepository.GetPage(
|
||||
Query<IMedia>().Where(x => x.ContentTypeId == contentTypeId),
|
||||
pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IMedia> GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, out long totalRecords, IQuery<IMedia> filter, Ordering ordering = null)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("sortOrder");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
return _mediaRepository.GetPage(
|
||||
Query<IMedia>().Where(x => contentTypeIds.Contains(x.ContentTypeId)),
|
||||
pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -393,12 +393,14 @@ namespace Umbraco.Core.Services.Implement
|
||||
|
||||
// fixme get rid of string filter?
|
||||
|
||||
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = "")
|
||||
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = "")
|
||||
{
|
||||
return GetAll(pageIndex, pageSize, out totalRecords, orderBy, orderDirection, true, memberTypeAlias, filter);
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, bool orderBySystemField, string memberTypeAlias, string filter)
|
||||
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, string memberTypeAlias, string filter)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
|
||||
@@ -333,92 +333,155 @@ namespace Umbraco.Web.Search
|
||||
|
||||
if (args.MessageType != MessageType.RefreshByPayload)
|
||||
throw new NotSupportedException();
|
||||
|
||||
var contentService = _services.ContentService;
|
||||
|
||||
var removedIds = new List<int>();
|
||||
var refreshedIds = new List<int>();
|
||||
var otherIds = new List<int>();
|
||||
|
||||
|
||||
var changedIds = new Dictionary<string, (List<int> removedIds, List<int> refreshedIds, List<int> otherIds)>();
|
||||
|
||||
foreach (var payload in (ContentTypeCacheRefresher.JsonPayload[])args.MessageObject)
|
||||
{
|
||||
if (!changedIds.TryGetValue(payload.ItemType, out var idLists))
|
||||
{
|
||||
idLists = (removedIds: new List<int>(), refreshedIds: new List<int>(), otherIds: new List<int>());
|
||||
changedIds.Add(payload.ItemType, idLists);
|
||||
}
|
||||
|
||||
if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.Remove))
|
||||
removedIds.Add(payload.Id);
|
||||
idLists.removedIds.Add(payload.Id);
|
||||
else if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.RefreshMain))
|
||||
refreshedIds.Add(payload.Id);
|
||||
idLists.refreshedIds.Add(payload.Id);
|
||||
else if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.RefreshOther))
|
||||
otherIds.Add(payload.Id);
|
||||
idLists.otherIds.Add(payload.Id);
|
||||
}
|
||||
|
||||
const int pageSize = 500;
|
||||
|
||||
if (refreshedIds.Count > 0 || otherIds.Count > 0)
|
||||
{
|
||||
foreach(var ci in changedIds)
|
||||
{
|
||||
if (ci.Value.refreshedIds.Count > 0 || ci.Value.otherIds.Count > 0)
|
||||
{
|
||||
switch(ci.Key)
|
||||
{
|
||||
case var itemType when itemType == typeof(IContentType).Name:
|
||||
RefreshContentOfContentTypes(ci.Value.refreshedIds.Concat(ci.Value.otherIds).Distinct().ToArray());
|
||||
break;
|
||||
case var itemType when itemType == typeof(IMediaType).Name:
|
||||
RefreshMediaOfMediaTypes(ci.Value.refreshedIds.Concat(ci.Value.otherIds).Distinct().ToArray());
|
||||
break;
|
||||
case var itemType when itemType == typeof(IMemberType).Name:
|
||||
RefreshMemberOfMemberTypes(ci.Value.refreshedIds.Concat(ci.Value.otherIds).Distinct().ToArray());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Delete all content of this content/media/member type that is in any content indexer by looking up matched examine docs
|
||||
foreach (var id in ci.Value.removedIds)
|
||||
{
|
||||
foreach (var index in _examineManager.IndexProviders.Values.OfType<UmbracoExamineIndexer>())
|
||||
{
|
||||
var searcher = index.GetSearcher();
|
||||
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
//paging with examine, see https://shazwazza.com/post/paging-with-examine/
|
||||
var results = searcher.Search(
|
||||
searcher.CreateCriteria().Field("nodeType", id).Compile(),
|
||||
maxResults: pageSize * (page + 1));
|
||||
total = results.TotalItemCount;
|
||||
var paged = results.Skip(page * pageSize);
|
||||
|
||||
foreach (var item in paged)
|
||||
if (int.TryParse(item.Id, out var contentId))
|
||||
DeleteIndexForEntity(contentId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshMemberOfMemberTypes(int[] memberTypeIds)
|
||||
{
|
||||
const int pageSize = 500;
|
||||
|
||||
var memberTypes = _services.MemberTypeService.GetAll(memberTypeIds);
|
||||
foreach(var memberType in memberTypes)
|
||||
{
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
var contentToRefresh = _services.ContentService.GetPagedOfTypes(
|
||||
//Re-index all content of these types
|
||||
refreshedIds.Concat(otherIds).Distinct().ToArray(),
|
||||
page++, pageSize, out total, null,
|
||||
//order by shallowest to deepest, this allows us to check it's published state without checking every item
|
||||
Ordering.By("Path", Direction.Ascending));
|
||||
var memberToRefresh = _services.MemberService.GetAll(
|
||||
page++, pageSize, out total, "LoginName", Direction.Ascending,
|
||||
memberType.Alias);
|
||||
|
||||
//track which Ids have their paths are published
|
||||
var publishChecked = new Dictionary<int, bool>();
|
||||
|
||||
foreach (var c in contentToRefresh)
|
||||
foreach (var c in memberToRefresh)
|
||||
{
|
||||
IContent published = null;
|
||||
if (c.Published)
|
||||
{
|
||||
if (publishChecked.TryGetValue(c.ParentId, out var isPublished))
|
||||
{
|
||||
//if the parent's published path has already been verified then this is published
|
||||
if (isPublished)
|
||||
published = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
//nothing by parent id, so query the service and cache the result for the next child to check against
|
||||
isPublished = contentService.IsPathPublished(c);
|
||||
publishChecked[c.Id] = isPublished;
|
||||
if (isPublished)
|
||||
published = c;
|
||||
}
|
||||
}
|
||||
|
||||
ReIndexForContent(c, published);
|
||||
ReIndexForMember(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Delete all content of this content type that is in any content indexer by looking up matched examine docs
|
||||
foreach(var id in removedIds)
|
||||
private void RefreshMediaOfMediaTypes(int[] mediaTypeIds)
|
||||
{
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
foreach(var index in _examineManager.IndexProviders.Values.OfType<UmbracoContentIndexer>())
|
||||
var mediaToRefresh = _services.MediaService.GetPagedOfTypes(
|
||||
//Re-index all content of these types
|
||||
mediaTypeIds,
|
||||
page++, pageSize, out total, null,
|
||||
Ordering.By("Path", Direction.Ascending));
|
||||
|
||||
foreach (var c in mediaToRefresh)
|
||||
{
|
||||
var searcher = index.GetSearcher();
|
||||
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
//paging with examine, see https://shazwazza.com/post/paging-with-examine/
|
||||
var results = searcher.Search(
|
||||
searcher.CreateCriteria().Field("nodeType", id).Compile(),
|
||||
maxResults: pageSize * (page + 1));
|
||||
total = results.TotalItemCount;
|
||||
var paged = results.Skip(page * pageSize);
|
||||
|
||||
foreach(var item in paged)
|
||||
if (int.TryParse(item.Id, out var contentId))
|
||||
DeleteIndexForEntity(contentId, false);
|
||||
}
|
||||
ReIndexForMedia(c, c.Trashed == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshContentOfContentTypes(int[] contentTypeIds)
|
||||
{
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
var contentToRefresh = _services.ContentService.GetPagedOfTypes(
|
||||
//Re-index all content of these types
|
||||
contentTypeIds,
|
||||
page++, pageSize, out total, null,
|
||||
//order by shallowest to deepest, this allows us to check it's published state without checking every item
|
||||
Ordering.By("Path", Direction.Ascending));
|
||||
|
||||
//track which Ids have their paths are published
|
||||
var publishChecked = new Dictionary<int, bool>();
|
||||
|
||||
foreach (var c in contentToRefresh)
|
||||
{
|
||||
IContent published = null;
|
||||
if (c.Published)
|
||||
{
|
||||
if (publishChecked.TryGetValue(c.ParentId, out var isPublished))
|
||||
{
|
||||
//if the parent's published path has already been verified then this is published
|
||||
if (isPublished)
|
||||
published = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
//nothing by parent id, so query the service and cache the result for the next child to check against
|
||||
isPublished = _services.ContentService.IsPathPublished(c);
|
||||
publishChecked[c.Id] = isPublished;
|
||||
if (isPublished)
|
||||
published = c;
|
||||
}
|
||||
}
|
||||
|
||||
ReIndexForContent(c, published);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user