U4-9395 When rebuilding content indexes that don't support unpublished content and member indexes, use the cmsContentXml table as the data source
This commit is contained in:
@@ -4,7 +4,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a ContentType, which Media is based on
|
||||
/// </summary
|
||||
/// </summary>
|
||||
public interface IMediaType : IContentTypeComposition
|
||||
{
|
||||
|
||||
|
||||
@@ -96,5 +96,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
IEnumerable<IContent> GetPagedResultsByQuery(IQuery<IContent> query, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, IQuery<IContent> filter = null);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -38,15 +38,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
IEnumerable<IMedia> GetPagedResultsByQuery(IQuery<IMedia> query, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, string filter = "");
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged media descendants as XML by path
|
||||
/// </summary>
|
||||
/// <param name="path">Path starts with</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records the query would return without paging</param>
|
||||
/// <returns>A paged enumerable of XML entries of media items</returns>
|
||||
IEnumerable<XElement> GetPagedXmlEntriesByPath(string path, long pageIndex, int pageSize, out long totalRecords);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="content"></param>
|
||||
/// <param name="xml"></param>
|
||||
void AddOrUpdatePreviewXml(IMember content, Func<IMember, XElement> xml);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -67,5 +67,15 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="id">Id of the <see cref="TEntity"/> object to delete versions from</param>
|
||||
/// <param name="versionDate">Latest version date</param>
|
||||
void DeleteVersions(int id, DateTime versionDate);
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged content descendants as XML by path
|
||||
/// </summary>
|
||||
/// <param name="path">Path starts with</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records the query would return without paging</param>
|
||||
/// <returns>A paged enumerable of XML entries of content items</returns>
|
||||
IEnumerable<XElement> GetPagedXmlEntriesByPath(string path, long pageIndex, int pageSize, out long totalRecords);
|
||||
}
|
||||
}
|
||||
@@ -502,30 +502,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged media descendants as XML by path
|
||||
/// </summary>
|
||||
/// <param name="path">Path starts with</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records the query would return without paging</param>
|
||||
/// <returns>A paged enumerable of XML entries of media items</returns>
|
||||
public IEnumerable<XElement> GetPagedXmlEntriesByPath(string path, long pageIndex, int pageSize, out long totalRecords)
|
||||
{
|
||||
Sql query;
|
||||
if (path == "-1")
|
||||
{
|
||||
query = new Sql().Select("nodeId, xml").From("cmsContentXml").Where("nodeId IN (SELECT id FROM umbracoNode WHERE nodeObjectType = @0)", Guid.Parse(Constants.ObjectTypes.Media)).OrderBy("nodeId");
|
||||
}
|
||||
else
|
||||
{
|
||||
query = new Sql().Select("nodeId, xml").From("cmsContentXml").Where("nodeId IN (SELECT id FROM umbracoNode WHERE path LIKE @0)", path.EnsureEndsWith(",%")).OrderBy("nodeId");
|
||||
}
|
||||
var pagedResult = Database.Page<ContentXmlDto>(pageIndex+1, pageSize, query);
|
||||
totalRecords = pagedResult.TotalItems;
|
||||
return pagedResult.Items.Select(dto => XElement.Parse(dto.Xml));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private method to create a media object from a ContentDto
|
||||
/// </summary>
|
||||
|
||||
@@ -381,7 +381,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.Where(GetBaseWhereClause(), new { Id = id })
|
||||
.OrderByDescending<ContentVersionDto>(x => x.VersionDate, SqlSyntax);
|
||||
return ProcessQuery(sql, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void RebuildXmlStructures(Func<IMember, XElement> serializer, int groupSize = 200, IEnumerable<int> contentTypeIds = null)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Logging;
|
||||
@@ -137,6 +138,30 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged content descendants as XML by path
|
||||
/// </summary>
|
||||
/// <param name="path">Path starts with</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records the query would return without paging</param>
|
||||
/// <returns>A paged enumerable of XML entries of content items</returns>
|
||||
public IEnumerable<XElement> GetPagedXmlEntriesByPath(string path, long pageIndex, int pageSize, out long totalRecords)
|
||||
{
|
||||
Sql query;
|
||||
if (path == "-1")
|
||||
{
|
||||
query = new Sql().Select("nodeId, xml").From("cmsContentXml").Where("nodeId IN (SELECT id FROM umbracoNode WHERE nodeObjectType = @0)", NodeObjectTypeId).OrderBy("nodeId");
|
||||
}
|
||||
else
|
||||
{
|
||||
query = new Sql().Select("nodeId, xml").From("cmsContentXml").Where("nodeId IN (SELECT id FROM umbracoNode WHERE path LIKE (@0))", path.EnsureEndsWith(",%")).OrderBy("nodeId");
|
||||
}
|
||||
var pagedResult = Database.Page<ContentXmlDto>(pageIndex + 1, pageSize, query);
|
||||
totalRecords = pagedResult.TotalItems;
|
||||
return pagedResult.Items.Select(dto => XElement.Parse(dto.Xml));
|
||||
}
|
||||
|
||||
public int CountDescendants(int parentId, string contentTypeAlias = null)
|
||||
{
|
||||
var pathMatch = parentId == -1
|
||||
|
||||
@@ -1764,6 +1764,27 @@ namespace Umbraco.Core.Services
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged content descendants as XML by path
|
||||
/// </summary>
|
||||
/// <param name="path">Path starts with</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records the query would return without paging</param>
|
||||
/// <returns>A paged enumerable of XML entries of content items</returns>
|
||||
public IEnumerable<XElement> GetPagedXmlEntries(string path, long pageIndex, int pageSize, out long totalRecords)
|
||||
{
|
||||
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
|
||||
Mandate.ParameterCondition(pageSize > 0, "pageSize");
|
||||
|
||||
var uow = UowProvider.GetUnitOfWork();
|
||||
using (var repository = RepositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
var contents = repository.GetPagedXmlEntriesByPath(path, pageIndex, pageSize, out totalRecords);
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This builds the Xml document used for the XML cache
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
@@ -95,6 +96,19 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public interface IContentService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all XML entries found in the cmsContentXml table based on the given path
|
||||
/// </summary>
|
||||
/// <param name="path">Path starts with</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records the query would return without paging</param>
|
||||
/// <returns>A paged enumerable of XML entries of content items</returns>
|
||||
/// <remarks>
|
||||
/// If -1 is passed, then this will return all content xml entries, otherwise will return all descendents from the path
|
||||
/// </remarks>
|
||||
IEnumerable<XElement> GetPagedXmlEntries(string path, long pageIndex, int pageSize, out long totalRecords);
|
||||
|
||||
/// <summary>
|
||||
/// This builds the Xml document used for the XML cache
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
@@ -13,6 +14,15 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public interface IMemberService : IMembershipMemberService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all XML entries found in the cmsContentXml table
|
||||
/// </summary>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records the query would return without paging</param>
|
||||
/// <returns>A paged enumerable of XML entries of content items</returns>
|
||||
IEnumerable<XElement> GetPagedXmlEntries(long pageIndex, int pageSize, out long totalRecords);
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds all xml content in the cmsContentXml table for all documents
|
||||
/// </summary>
|
||||
|
||||
@@ -612,6 +612,26 @@ namespace Umbraco.Core.Services
|
||||
Audit(AuditType.Publish, "MemberService.RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged member descendants as XML by path
|
||||
/// </summary>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records the query would return without paging</param>
|
||||
/// <returns>A paged enumerable of XML entries of member items</returns>
|
||||
public IEnumerable<XElement> GetPagedXmlEntries(long pageIndex, int pageSize, out long totalRecords)
|
||||
{
|
||||
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
|
||||
Mandate.ParameterCondition(pageSize > 0, "pageSize");
|
||||
|
||||
var uow = UowProvider.GetUnitOfWork();
|
||||
using (var repository = RepositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
var contents = repository.GetPagedXmlEntriesByPath("-1", pageIndex, pageSize, out totalRecords);
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMembershipMemberService Implementation
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Examine;
|
||||
using Lucene.Net.Documents;
|
||||
@@ -230,7 +231,13 @@ namespace UmbracoExamine
|
||||
SupportProtectedContent = supportProtected;
|
||||
else
|
||||
SupportProtectedContent = false;
|
||||
|
||||
|
||||
bool disableXmlDocLookup;
|
||||
if (config["disableXmlDocLookup"] != null && bool.TryParse(config["disableXmlDocLookup"], out disableXmlDocLookup))
|
||||
DisableXmlDocumentLookup = disableXmlDocLookup;
|
||||
else
|
||||
DisableXmlDocumentLookup = false;
|
||||
|
||||
base.Initialize(name, config);
|
||||
}
|
||||
|
||||
@@ -238,6 +245,11 @@ namespace UmbracoExamine
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use the cmsContentXml data to re-index when possible (i.e. for published content, media and members)
|
||||
/// </summary>
|
||||
public bool DisableXmlDocumentLookup { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// By default this is false, if set to true then the indexer will include indexing content that is flagged as publicly protected.
|
||||
/// This property is ignored if SupportUnpublishedContent is set to true.
|
||||
@@ -364,6 +376,9 @@ namespace UmbracoExamine
|
||||
|
||||
protected override void PerformIndexAll(string type)
|
||||
{
|
||||
if (SupportedTypes.Contains(type) == false)
|
||||
return;
|
||||
|
||||
const int pageSize = 10000;
|
||||
var pageIndex = 0;
|
||||
|
||||
@@ -371,111 +386,171 @@ namespace UmbracoExamine
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
switch (type)
|
||||
try
|
||||
{
|
||||
case IndexTypes.Content:
|
||||
var contentParentId = -1;
|
||||
if (IndexerData.ParentNodeId.HasValue && IndexerData.ParentNodeId.Value > 0)
|
||||
{
|
||||
contentParentId = IndexerData.ParentNodeId.Value;
|
||||
}
|
||||
IContent[] content;
|
||||
|
||||
//used to track non-published entities so we can determine what items are implicitly not published
|
||||
var notPublished = new HashSet<string>();
|
||||
|
||||
do
|
||||
{
|
||||
long total;
|
||||
|
||||
IEnumerable<IContent> descendants;
|
||||
if (SupportUnpublishedContent)
|
||||
switch (type)
|
||||
{
|
||||
case IndexTypes.Content:
|
||||
var contentParentId = -1;
|
||||
if (IndexerData.ParentNodeId.HasValue && IndexerData.ParentNodeId.Value > 0)
|
||||
{
|
||||
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total);
|
||||
}
|
||||
else
|
||||
{
|
||||
//get all paged records but order by level ascending, we need to do this because we need to track which nodes are not published so that we can determine
|
||||
// which descendent nodes are implicitly not published
|
||||
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "level", Direction.Ascending, true, (string)null);
|
||||
}
|
||||
|
||||
//if specific types are declared we need to post filter them
|
||||
//TODO: Update the service layer to join the cmsContentType table so we can query by content type too
|
||||
if (IndexerData.IncludeNodeTypes.Any())
|
||||
{
|
||||
content = descendants.Where(x => IndexerData.IncludeNodeTypes.Contains(x.ContentType.Alias)).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
content = descendants.ToArray();
|
||||
}
|
||||
|
||||
AddNodesToIndex(GetSerializedContent(
|
||||
SupportUnpublishedContent,
|
||||
c => _serializer.Serialize(_contentService, _dataTypeService, _userService, c),
|
||||
content, notPublished).WhereNotNull(), type);
|
||||
|
||||
pageIndex++;
|
||||
} while (content.Length == pageSize);
|
||||
|
||||
notPublished.Clear();
|
||||
|
||||
break;
|
||||
case IndexTypes.Media:
|
||||
var mediaParentId = -1;
|
||||
|
||||
if (IndexerData.ParentNodeId.HasValue && IndexerData.ParentNodeId.Value > 0)
|
||||
{
|
||||
mediaParentId = IndexerData.ParentNodeId.Value;
|
||||
}
|
||||
|
||||
XElement[] mediaXElements;
|
||||
|
||||
var mediaTypes = _contentTypeService.GetAllMediaTypes().ToArray();
|
||||
var icons = mediaTypes.ToDictionary(x => x.Id, y => y.Icon);
|
||||
|
||||
do
|
||||
{
|
||||
long total;
|
||||
if (mediaParentId == -1)
|
||||
{
|
||||
mediaXElements = _mediaService.GetPagedXmlEntries("-1", pageIndex, pageSize, out total).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
//Get the parent
|
||||
var parent = _mediaService.GetById(mediaParentId);
|
||||
if (parent == null)
|
||||
mediaXElements = new XElement[0];
|
||||
else
|
||||
mediaXElements = _mediaService.GetPagedXmlEntries(parent.Path, pageIndex, pageSize, out total).ToArray();
|
||||
}
|
||||
|
||||
//if specific types are declared we need to post filter them
|
||||
//TODO: Update the service layer to join the cmsContentType table so we can query by content type too
|
||||
if (IndexerData.IncludeNodeTypes.Any())
|
||||
{
|
||||
var includeNodeTypeIds = mediaTypes.Where(x => IndexerData.IncludeNodeTypes.Contains(x.Alias)).Select(x => x.Id);
|
||||
mediaXElements = mediaXElements.Where(elm => includeNodeTypeIds.Contains(elm.AttributeValue<int>("nodeType"))).ToArray();
|
||||
contentParentId = IndexerData.ParentNodeId.Value;
|
||||
}
|
||||
|
||||
foreach (var element in mediaXElements)
|
||||
if (SupportUnpublishedContent == false && DisableXmlDocumentLookup == false)
|
||||
{
|
||||
element.Add(new XAttribute("icon", icons[element.AttributeValue<int>("nodeType")]));
|
||||
ReindexWithXmlEntries(type, contentParentId,
|
||||
() => _contentTypeService.GetAllContentTypes().ToArray(),
|
||||
(path, pIndex, pSize) =>
|
||||
{
|
||||
long totalContent;
|
||||
var result = _contentService.GetPagedXmlEntries(path, pIndex, pSize, out totalContent).ToArray();
|
||||
return new Tuple<long, XElement[]>(totalContent, result);
|
||||
},
|
||||
i => _contentService.GetById(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
//used to track non-published entities so we can determine what items are implicitly not published
|
||||
//currently this is not in use apart form in tests
|
||||
var notPublished = new HashSet<string>();
|
||||
|
||||
IContent[] content;
|
||||
do
|
||||
{
|
||||
long total;
|
||||
|
||||
IEnumerable<IContent> descendants;
|
||||
if (SupportUnpublishedContent)
|
||||
{
|
||||
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total);
|
||||
}
|
||||
else
|
||||
{
|
||||
//get all paged records but order by level ascending, we need to do this because we need to track which nodes are not published so that we can determine
|
||||
// which descendent nodes are implicitly not published
|
||||
descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "level", Direction.Ascending, true, (string)null);
|
||||
}
|
||||
|
||||
//if specific types are declared we need to post filter them
|
||||
//TODO: Update the service layer to join the cmsContentType table so we can query by content type too
|
||||
if (IndexerData.IncludeNodeTypes.Any())
|
||||
{
|
||||
content = descendants.Where(x => IndexerData.IncludeNodeTypes.Contains(x.ContentType.Alias)).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
content = descendants.ToArray();
|
||||
}
|
||||
|
||||
AddNodesToIndex(GetSerializedContent(
|
||||
SupportUnpublishedContent,
|
||||
c => _serializer.Serialize(_contentService, _dataTypeService, _userService, c),
|
||||
content, notPublished).WhereNotNull(), type);
|
||||
|
||||
pageIndex++;
|
||||
} while (content.Length == pageSize);
|
||||
}
|
||||
|
||||
AddNodesToIndex(mediaXElements, type);
|
||||
pageIndex++;
|
||||
} while (mediaXElements.Length == pageSize);
|
||||
break;
|
||||
case IndexTypes.Media:
|
||||
var mediaParentId = -1;
|
||||
|
||||
break;
|
||||
if (IndexerData.ParentNodeId.HasValue && IndexerData.ParentNodeId.Value > 0)
|
||||
{
|
||||
mediaParentId = IndexerData.ParentNodeId.Value;
|
||||
}
|
||||
|
||||
ReindexWithXmlEntries(type, mediaParentId,
|
||||
() => _contentTypeService.GetAllMediaTypes().ToArray(),
|
||||
(path, pIndex, pSize) =>
|
||||
{
|
||||
long totalMedia;
|
||||
var result = _mediaService.GetPagedXmlEntries(path, pIndex, pSize, out totalMedia).ToArray();
|
||||
return new Tuple<long, XElement[]>(totalMedia, result);
|
||||
},
|
||||
i => _mediaService.GetById(i));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
finally
|
||||
{
|
||||
stopwatch.Stop();
|
||||
}
|
||||
|
||||
DataService.LogService.AddInfoLog(-1, string.Format("PerformIndexAll - End data queries - {0}, took {1}ms", type, stopwatch.ElapsedMilliseconds));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a reindex of a type based on looking up entries from the cmsContentXml table - but using callbacks to get this data since
|
||||
/// we don't have a common underlying service interface for the media/content stuff
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="parentId"></param>
|
||||
/// <param name="getContentTypes"></param>
|
||||
/// <param name="getPagedXmlEntries"></param>
|
||||
/// <param name="getContent"></param>
|
||||
internal void ReindexWithXmlEntries<TContentType>(
|
||||
string type,
|
||||
int parentId,
|
||||
Func<TContentType[]> getContentTypes,
|
||||
Func<string, int, int, Tuple<long, XElement[]>> getPagedXmlEntries,
|
||||
Func<int, IContentBase> getContent)
|
||||
where TContentType: IContentTypeComposition
|
||||
{
|
||||
const int pageSize = 10000;
|
||||
var pageIndex = 0;
|
||||
|
||||
XElement[] xElements;
|
||||
|
||||
var contentTypes = getContentTypes();
|
||||
var icons = contentTypes.ToDictionary(x => x.Id, y => y.Icon);
|
||||
|
||||
do
|
||||
{
|
||||
long total;
|
||||
if (parentId == -1)
|
||||
{
|
||||
var pagedElements = getPagedXmlEntries("-1", pageIndex, pageSize);
|
||||
total = pagedElements.Item1;
|
||||
xElements = pagedElements.Item2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Get the parent
|
||||
var parent = getContent(parentId);
|
||||
if (parent == null)
|
||||
xElements = new XElement[0];
|
||||
else
|
||||
{
|
||||
var pagedElements = getPagedXmlEntries(parent.Path, pageIndex, pageSize);
|
||||
total = pagedElements.Item1;
|
||||
xElements = pagedElements.Item2;
|
||||
}
|
||||
}
|
||||
|
||||
//if specific types are declared we need to post filter them
|
||||
//TODO: Update the service layer to join the cmsContentType table so we can query by content type too
|
||||
if (IndexerData.IncludeNodeTypes.Any())
|
||||
{
|
||||
var includeNodeTypeIds = contentTypes.Where(x => IndexerData.IncludeNodeTypes.Contains(x.Alias)).Select(x => x.Id);
|
||||
xElements = xElements.Where(elm => includeNodeTypeIds.Contains(elm.AttributeValue<int>("nodeType"))).ToArray();
|
||||
}
|
||||
|
||||
foreach (var element in xElements)
|
||||
{
|
||||
if (element.Attribute("icon") == null)
|
||||
{
|
||||
element.Add(new XAttribute("icon", icons[element.AttributeValue<int>("nodeType")]));
|
||||
}
|
||||
}
|
||||
|
||||
AddNodesToIndex(xElements, type);
|
||||
pageIndex++;
|
||||
} while (xElements.Length == pageSize);
|
||||
}
|
||||
|
||||
internal static IEnumerable<XElement> GetSerializedContent(
|
||||
bool supportUnpublishdContent,
|
||||
Func<IContent, XElement> serializer,
|
||||
|
||||
@@ -9,6 +9,7 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Services;
|
||||
using UmbracoExamine.Config;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using Examine;
|
||||
using System.IO;
|
||||
@@ -25,6 +26,7 @@ namespace UmbracoExamine
|
||||
{
|
||||
|
||||
private readonly IMemberService _memberService;
|
||||
private readonly IMemberTypeService _memberTypeService;
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
|
||||
/// <summary>
|
||||
@@ -34,6 +36,7 @@ namespace UmbracoExamine
|
||||
{
|
||||
_dataTypeService = ApplicationContext.Current.Services.DataTypeService;
|
||||
_memberService = ApplicationContext.Current.Services.MemberService;
|
||||
_memberTypeService = ApplicationContext.Current.Services.MemberTypeService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,6 +52,7 @@ namespace UmbracoExamine
|
||||
{
|
||||
_dataTypeService = ApplicationContext.Current.Services.DataTypeService;
|
||||
_memberService = ApplicationContext.Current.Services.MemberService;
|
||||
_memberTypeService = ApplicationContext.Current.Services.MemberTypeService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -61,6 +65,8 @@ namespace UmbracoExamine
|
||||
/// <param name="memberService"></param>
|
||||
/// <param name="analyzer"></param>
|
||||
/// <param name="async"></param>
|
||||
[Obsolete("Use the ctor specifying all dependencies instead")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public UmbracoMemberIndexer(IIndexCriteria indexerData, DirectoryInfo indexPath, IDataService dataService,
|
||||
IDataTypeService dataTypeService,
|
||||
IMemberService memberService,
|
||||
@@ -69,9 +75,31 @@ namespace UmbracoExamine
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_memberService = memberService;
|
||||
_memberTypeService = ApplicationContext.Current.Services.MemberTypeService;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to allow for creating an indexer at runtime
|
||||
/// </summary>
|
||||
/// <param name="indexerData"></param>
|
||||
/// <param name="indexPath"></param>
|
||||
/// <param name="dataService"></param>
|
||||
/// <param name="dataTypeService"></param>
|
||||
/// <param name="memberService"></param>
|
||||
/// <param name="memberTypeService"></param>
|
||||
/// <param name="analyzer"></param>
|
||||
/// <param name="async"></param>
|
||||
public UmbracoMemberIndexer(IIndexCriteria indexerData, DirectoryInfo indexPath, IDataService dataService,
|
||||
IDataTypeService dataTypeService,
|
||||
IMemberService memberService,
|
||||
IMemberTypeService memberTypeService,
|
||||
Analyzer analyzer, bool async)
|
||||
: base(indexerData, indexPath, dataService, analyzer, async)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_memberService = memberService;
|
||||
_memberTypeService = memberTypeService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the'_searchEmail' is added to the user fields so that it is indexed - without having to modify the config
|
||||
@@ -130,46 +158,67 @@ namespace UmbracoExamine
|
||||
if (SupportedTypes.Contains(type) == false)
|
||||
return;
|
||||
|
||||
const int pageSize = 1000;
|
||||
var pageIndex = 0;
|
||||
|
||||
DataService.LogService.AddInfoLog(-1, string.Format("PerformIndexAll - Start data queries - {0}", type));
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
IMember[] members;
|
||||
|
||||
if (IndexerData.IncludeNodeTypes.Any())
|
||||
try
|
||||
{
|
||||
//if there are specific node types then just index those
|
||||
foreach (var nodeType in IndexerData.IncludeNodeTypes)
|
||||
if (DisableXmlDocumentLookup == false)
|
||||
{
|
||||
do
|
||||
ReindexWithXmlEntries(type, -1,
|
||||
() => _memberTypeService.GetAll().ToArray(),
|
||||
(path, pIndex, pSize) =>
|
||||
{
|
||||
long totalContent;
|
||||
var result = _memberService.GetPagedXmlEntries(pIndex, pSize, out totalContent).ToArray();
|
||||
return new Tuple<long, XElement[]>(totalContent, result);
|
||||
},
|
||||
i => _memberService.GetById(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
const int pageSize = 1000;
|
||||
var pageIndex = 0;
|
||||
|
||||
IMember[] members;
|
||||
|
||||
if (IndexerData.IncludeNodeTypes.Any())
|
||||
{
|
||||
long total;
|
||||
members = _memberService.GetAll(pageIndex, pageSize, out total, "LoginName", Direction.Ascending, true, null, nodeType).ToArray();
|
||||
//if there are specific node types then just index those
|
||||
foreach (var nodeType in IndexerData.IncludeNodeTypes)
|
||||
{
|
||||
do
|
||||
{
|
||||
long total;
|
||||
members = _memberService.GetAll(pageIndex, pageSize, out total, "LoginName", Direction.Ascending, true, null, nodeType).ToArray();
|
||||
|
||||
AddNodesToIndex(GetSerializedMembers(members), type);
|
||||
AddNodesToIndex(GetSerializedMembers(members), type);
|
||||
|
||||
pageIndex++;
|
||||
} while (members.Length == pageSize);
|
||||
pageIndex++;
|
||||
} while (members.Length == pageSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//no node types specified, do all members
|
||||
do
|
||||
{
|
||||
int total;
|
||||
members = _memberService.GetAll(pageIndex, pageSize, out total).ToArray();
|
||||
|
||||
AddNodesToIndex(GetSerializedMembers(members), type);
|
||||
|
||||
pageIndex++;
|
||||
} while (members.Length == pageSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
finally
|
||||
{
|
||||
//no node types specified, do all members
|
||||
do
|
||||
{
|
||||
int total;
|
||||
members = _memberService.GetAll(pageIndex, pageSize, out total).ToArray();
|
||||
|
||||
AddNodesToIndex(GetSerializedMembers(members), type);
|
||||
|
||||
pageIndex++;
|
||||
} while (members.Length == pageSize);
|
||||
stopwatch.Stop();
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
DataService.LogService.AddInfoLog(-1, string.Format("PerformIndexAll - End data queries - {0}, took {1}ms", type, stopwatch.ElapsedMilliseconds));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user