* add option to interface * pass config to picker * add option to interface * force type * add request args to type * pass allowed content types as request args * add comments * allow for passing type * more type safety * use correct types * use correct types * add js docs * remove debugger + map to only pass id to server * add js docs * align naming * add null check * align types * implement allowedContentTypes for member search * fix imports * add types for media search * add and use const * align picker interfaces * align models * add entity type * filter for null value * explicit naming * rename field * use query params * Implement content type scoped search in item search controllers * Fix bad naming * generate server models * wire up backend * generate server models * add selectable filter to member picker * Update member-picker-modal.element.ts * Fix indexed search for specific member and media types * export consts --------- Co-authored-by: kjac <kja@umbraco.dk>
115 lines
4.7 KiB
C#
115 lines
4.7 KiB
C#
using Examine;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Umbraco.Cms.Core;
|
|
using Umbraco.Cms.Core.DependencyInjection;
|
|
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 IndexedEntitySearchService : IIndexedEntitySearchService
|
|
{
|
|
private readonly IBackOfficeExamineSearcher _backOfficeExamineSearcher;
|
|
private readonly IEntityService _entityService;
|
|
private readonly IContentTypeService _contentTypeService;
|
|
private readonly IMediaTypeService _mediaTypeService;
|
|
private readonly IMemberTypeService _memberTypeService;
|
|
|
|
public IndexedEntitySearchService(IBackOfficeExamineSearcher backOfficeExamineSearcher, IEntityService entityService)
|
|
: this(
|
|
backOfficeExamineSearcher,
|
|
entityService,
|
|
StaticServiceProvider.Instance.GetRequiredService<IContentTypeService>(),
|
|
StaticServiceProvider.Instance.GetRequiredService<IMediaTypeService>(),
|
|
StaticServiceProvider.Instance.GetRequiredService<IMemberTypeService>())
|
|
{
|
|
}
|
|
|
|
public IndexedEntitySearchService(
|
|
IBackOfficeExamineSearcher backOfficeExamineSearcher,
|
|
IEntityService entityService,
|
|
IContentTypeService contentTypeService,
|
|
IMediaTypeService mediaTypeService,
|
|
IMemberTypeService memberTypeService)
|
|
{
|
|
_backOfficeExamineSearcher = backOfficeExamineSearcher;
|
|
_entityService = entityService;
|
|
_contentTypeService = contentTypeService;
|
|
_mediaTypeService = mediaTypeService;
|
|
_memberTypeService = memberTypeService;
|
|
}
|
|
|
|
public PagedModel<IEntitySlim> Search(UmbracoObjectTypes objectType, string query, int skip = 0, int take = 100, bool ignoreUserStartNodes = false)
|
|
=> Search(objectType, query, null, skip, take, ignoreUserStartNodes);
|
|
|
|
public PagedModel<IEntitySlim> Search(
|
|
UmbracoObjectTypes objectType,
|
|
string query,
|
|
Guid? parentId,
|
|
int skip = 0,
|
|
int take = 100,
|
|
bool ignoreUserStartNodes = false)
|
|
=> Search(objectType, query, parentId, null, skip, take, ignoreUserStartNodes);
|
|
|
|
public PagedModel<IEntitySlim> Search(
|
|
UmbracoObjectTypes objectType,
|
|
string query,
|
|
Guid? parentId,
|
|
IEnumerable<Guid>? contentTypeIds,
|
|
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);
|
|
|
|
Guid[]? contentTypeIdsAsArray = contentTypeIds as Guid[] ?? contentTypeIds?.ToArray();
|
|
var contentTypeAliases = contentTypeIdsAsArray?.Length > 0
|
|
? (entityType switch
|
|
{
|
|
UmbracoEntityTypes.Document => _contentTypeService.GetMany(contentTypeIdsAsArray).Select(x => x.Alias),
|
|
UmbracoEntityTypes.Media => _mediaTypeService.GetMany(contentTypeIdsAsArray).Select(x => x.Alias),
|
|
UmbracoEntityTypes.Member => _memberTypeService.GetMany(contentTypeIdsAsArray).Select(x => x.Alias),
|
|
_ => throw new NotSupportedException("This service only supports searching for documents, media and members")
|
|
}).ToArray()
|
|
: null;
|
|
|
|
IEnumerable<ISearchResult> searchResults = _backOfficeExamineSearcher.Search(
|
|
query,
|
|
entityType,
|
|
pageSize,
|
|
pageNumber,
|
|
out var totalFound,
|
|
contentTypeAliases,
|
|
ignoreUserStartNodes: ignoreUserStartNodes,
|
|
searchFrom: parentId?.ToString());
|
|
|
|
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
|
|
};
|
|
}
|
|
}
|