Examine entity search for documents, media and members (#15972)

This commit is contained in:
Kenn Jacobsen
2024-04-03 18:49:23 +02:00
committed by GitHub
parent a95a092c39
commit 75b1d4729f
6 changed files with 81 additions and 15 deletions

View File

@@ -12,12 +12,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.Item;
[ApiVersion("1.0")]
public class SearchDocumentItemController : DocumentItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IExamineEntitySearchService _examineEntitySearchService;
private readonly IDocumentPresentationFactory _documentPresentationFactory;
public SearchDocumentItemController(IEntitySearchService entitySearchService, IDocumentPresentationFactory documentPresentationFactory)
public SearchDocumentItemController(IExamineEntitySearchService examineEntitySearchService, IDocumentPresentationFactory documentPresentationFactory)
{
_entitySearchService = entitySearchService;
_examineEntitySearchService = examineEntitySearchService;
_documentPresentationFactory = documentPresentationFactory;
}
@@ -26,8 +26,7 @@ public class SearchDocumentItemController : DocumentItemControllerBase
[ProducesResponseType(typeof(PagedModel<DocumentItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
// FIXME: use Examine and handle user start nodes
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.Document, query, skip, take);
PagedModel<IEntitySlim> searchResult = _examineEntitySearchService.Search(UmbracoObjectTypes.Document, query, skip, take);
var result = new PagedModel<DocumentItemResponseModel>
{
Items = searchResult.Items.OfType<IDocumentEntitySlim>().Select(_documentPresentationFactory.CreateItemResponseModel),

View File

@@ -12,12 +12,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.Media.Item;
[ApiVersion("1.0")]
public class SearchMediaItemController : MediaItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IExamineEntitySearchService _examineEntitySearchService;
private readonly IMediaPresentationFactory _mediaPresentationFactory;
public SearchMediaItemController(IEntitySearchService entitySearchService, IMediaPresentationFactory mediaPresentationFactory)
public SearchMediaItemController(IExamineEntitySearchService examineEntitySearchService, IMediaPresentationFactory mediaPresentationFactory)
{
_entitySearchService = entitySearchService;
_examineEntitySearchService = examineEntitySearchService;
_mediaPresentationFactory = mediaPresentationFactory;
}
@@ -26,8 +26,7 @@ public class SearchMediaItemController : MediaItemControllerBase
[ProducesResponseType(typeof(PagedModel<MediaItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
// FIXME: use Examine and handle user start nodes
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.Media, query, skip, take);
PagedModel<IEntitySlim> searchResult = _examineEntitySearchService.Search(UmbracoObjectTypes.Media, query, skip, take);
var result = new PagedModel<MediaItemResponseModel>
{
Items = searchResult.Items.OfType<IMediaEntitySlim>().Select(_mediaPresentationFactory.CreateItemResponseModel),

View File

@@ -12,12 +12,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.Member.Item;
[ApiVersion("1.0")]
public class SearchMemberItemController : MemberItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IExamineEntitySearchService _examineEntitySearchService;
private readonly IMemberPresentationFactory _memberPresentationFactory;
public SearchMemberItemController(IEntitySearchService entitySearchService, IMemberPresentationFactory memberPresentationFactory)
public SearchMemberItemController(IExamineEntitySearchService examineEntitySearchService, IMemberPresentationFactory memberPresentationFactory)
{
_entitySearchService = entitySearchService;
_examineEntitySearchService = examineEntitySearchService;
_memberPresentationFactory = memberPresentationFactory;
}
@@ -26,8 +26,7 @@ public class SearchMemberItemController : MemberItemControllerBase
[ProducesResponseType(typeof(PagedModel<MemberItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
// FIXME: use Examine
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.Member, query, skip, take);
PagedModel<IEntitySlim> searchResult = _examineEntitySearchService.Search(UmbracoObjectTypes.Member, query, skip, take);
var result = new PagedModel<MemberItemResponseModel>
{
Items = searchResult.Items.OfType<IMemberEntitySlim>().Select(_memberPresentationFactory.CreateItemResponseModel),

View File

@@ -0,0 +1,9 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
namespace Umbraco.Cms.Core.Services;
public interface IExamineEntitySearchService
{
PagedModel<IEntitySlim> Search(UmbracoObjectTypes objectType, string query, int skip = 0, int take = 100, bool ignoreUserStartNodes = false);
}

View File

@@ -63,6 +63,7 @@ public static partial class UmbracoBuilderExtensions
builder.Services.AddUnique<IContentListViewService, ContentListViewService>();
builder.Services.AddUnique<IMediaListViewService, MediaListViewService>();
builder.Services.AddUnique<IEntitySearchService, EntitySearchService>();
builder.Services.AddUnique<IExamineEntitySearchService, ExamineEntitySearchService>();
return builder;
}

View File

@@ -0,0 +1,59 @@
using Examine;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Examine;
namespace Umbraco.Cms.Infrastructure.Services.Implement;
internal sealed class ExamineEntitySearchService : IExamineEntitySearchService
{
private readonly IBackOfficeExamineSearcher _backOfficeExamineSearcher;
private readonly IEntityService _entityService;
public ExamineEntitySearchService(IBackOfficeExamineSearcher backOfficeExamineSearcher, IEntityService entityService)
{
_backOfficeExamineSearcher = backOfficeExamineSearcher;
_entityService = entityService;
}
public PagedModel<IEntitySlim> Search(UmbracoObjectTypes objectType, string query, int skip = 0, int take = 100, bool ignoreUserStartNodes = false)
{
UmbracoEntityTypes entityType = objectType switch
{
UmbracoObjectTypes.Document => UmbracoEntityTypes.Document,
UmbracoObjectTypes.Media => UmbracoEntityTypes.Media,
UmbracoObjectTypes.Member => UmbracoEntityTypes.Member,
_ => throw new NotSupportedException("This service only supports searching for documents, media and members")
};
PaginationHelper.ConvertSkipTakeToPaging(skip, take, out var pageNumber, out var pageSize);
IEnumerable<ISearchResult> searchResults = _backOfficeExamineSearcher.Search(
query,
entityType,
pageSize,
pageNumber,
out var totalFound,
ignoreUserStartNodes: ignoreUserStartNodes);
Guid[] keys = searchResults.Select(
result =>
result.Values.TryGetValue(UmbracoExamineFieldNames.NodeKeyFieldName, out var keyValue) &&
Guid.TryParse(keyValue, out Guid key)
? key
: Guid.Empty)
.Where(key => key != Guid.Empty)
.ToArray();
return new PagedModel<IEntitySlim>
{
Items = keys.Any()
? _entityService.GetAll(objectType, keys)
: Enumerable.Empty<IEntitySlim>(),
Total = totalFound
};
}
}