Support parentId in document/media item search endpoints (#16933)

* Updated search services to start searching from a guid based key.

* Solved api breaking changes with new minor version

* Ordering and formatting

* Changed interface default implementation to the new method...

* Consolidated version

* PR review cleanup and renaming
This commit is contained in:
Sven Geusens
2024-08-27 15:18:25 +02:00
committed by GitHub
parent 3f8bae1a29
commit 27108036b4
5 changed files with 41 additions and 9 deletions

View File

@@ -21,16 +21,21 @@ public class SearchDocumentItemController : DocumentItemControllerBase
_documentPresentationFactory = documentPresentationFactory;
}
[NonAction]
[Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")]
public async Task<IActionResult> Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100)
=> await SearchFromParent(cancellationToken, query, skip, take);
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<DocumentItemResponseModel>), StatusCodes.Status200OK)]
public async Task<IActionResult> Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100)
public async Task<IActionResult> SearchFromParent(CancellationToken cancellationToken, string query, int skip = 0, int take = 100, Guid? parentId = null)
{
PagedModel<IEntitySlim> searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Document, query, skip, take);
PagedModel<IEntitySlim> searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Document, query, parentId, skip, take);
var result = new PagedModel<DocumentItemResponseModel>
{
Items = searchResult.Items.OfType<IDocumentEntitySlim>().Select(_documentPresentationFactory.CreateItemResponseModel),
Total = searchResult.Total
Total = searchResult.Total,
};
return await Task.FromResult(Ok(result));

View File

@@ -21,16 +21,21 @@ public class SearchMediaItemController : MediaItemControllerBase
_mediaPresentationFactory = mediaPresentationFactory;
}
[NonAction]
[Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")]
public async Task<IActionResult> Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100)
=> await SearchFromParent(cancellationToken, query, skip, take, null);
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<MediaItemResponseModel>), StatusCodes.Status200OK)]
public async Task<IActionResult> Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100)
public async Task<IActionResult> SearchFromParent(CancellationToken cancellationToken, string query, int skip = 0, int take = 100, Guid? parentId = null)
{
PagedModel<IEntitySlim> searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Media, query, skip, take);
PagedModel<IEntitySlim> searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Media, query, parentId, skip, take);
var result = new PagedModel<MediaItemResponseModel>
{
Items = searchResult.Items.OfType<IMediaEntitySlim>().Select(_mediaPresentationFactory.CreateItemResponseModel),
Total = searchResult.Total
Total = searchResult.Total,
};
return await Task.FromResult(Ok(result));

View File

@@ -13,4 +13,8 @@ namespace Umbraco.Cms.Core.Services;
public interface IIndexedEntitySearchService
{
PagedModel<IEntitySlim> Search(UmbracoObjectTypes objectType, string query, int skip = 0, int take = 100, bool ignoreUserStartNodes = false);
// default implementation to avoid breaking changes falls back to old behaviour
PagedModel<IEntitySlim> Search(UmbracoObjectTypes objectType, string query, Guid? parentId, int skip = 0, int take = 100, bool ignoreUserStartNodes = false)
=> Search(objectType,query, skip, take, ignoreUserStartNodes);
}

View File

@@ -356,8 +356,16 @@ public class BackOfficeExamineSearcher : IBackOfficeExamineSearcher
throw new ArgumentNullException(nameof(entityService));
}
UdiParser.TryParse(searchFrom, true, out Udi? udi);
searchFrom = udi == null ? searchFrom : entityService.GetId(udi).Result.ToString();
if (Guid.TryParse(searchFrom, out Guid guid))
{
searchFrom = entityService.GetId(guid, objectType).Result.ToString();
}
else
{
// fallback to Udi for legacy reasons as the calling methods take string?
UdiParser.TryParse(searchFrom, true, out Udi? udi);
searchFrom = udi == null ? searchFrom : entityService.GetId(udi).Result.ToString();
}
TreeEntityPath? entityPath =
int.TryParse(searchFrom, NumberStyles.Integer, CultureInfo.InvariantCulture, out var searchFromId) &&

View File

@@ -20,6 +20,15 @@ internal sealed class IndexedEntitySearchService : IIndexedEntitySearchService
}
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)
{
UmbracoEntityTypes entityType = objectType switch
{
@@ -37,7 +46,8 @@ internal sealed class IndexedEntitySearchService : IIndexedEntitySearchService
pageSize,
pageNumber,
out var totalFound,
ignoreUserStartNodes: ignoreUserStartNodes);
ignoreUserStartNodes: ignoreUserStartNodes,
searchFrom: parentId?.ToString());
Guid[] keys = searchResults.Select(
result =>