aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers/ItemsController.cs
diff options
context:
space:
mode:
authorNiels van Velzen <nielsvanvelzen@users.noreply.github.com>2026-05-03 21:56:34 +0200
committerGitHub <noreply@github.com>2026-05-03 21:56:34 +0200
commit6e22075a63432aae48859cf9c67fde158dc80d2e (patch)
treec3a33238cc56857d8e3daa56db01f290118c9215 /Jellyfin.Api/Controllers/ItemsController.cs
parentd9ced0d6399c82ddad9e983605bb0d828a608e63 (diff)
parentd68d0fa96267ad96eaa5a0ba37e072f59a71442a (diff)
Merge pull request #16062 from Shadowghost/perf-rebased
Query Performance Improvements
Diffstat (limited to 'Jellyfin.Api/Controllers/ItemsController.cs')
-rw-r--r--Jellyfin.Api/Controllers/ItemsController.cs26
1 files changed, 21 insertions, 5 deletions
diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs
index 69cdba6afd..53656186c8 100644
--- a/Jellyfin.Api/Controllers/ItemsController.cs
+++ b/Jellyfin.Api/Controllers/ItemsController.cs
@@ -1,6 +1,7 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
+using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
@@ -161,7 +162,7 @@ public class ItemsController : BaseJellyfinApiController
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the items.</returns>
[HttpGet("Items")]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<QueryResult<BaseItemDto>> GetItems(
+ public async Task<ActionResult<QueryResult<BaseItemDto>>> GetItems(
[FromQuery] Guid? userId,
[FromQuery] string? maxOfficialRating,
[FromQuery] bool? hasThemeSong,
@@ -299,6 +300,21 @@ public class ItemsController : BaseJellyfinApiController
recursive = true;
includeItemTypes = new[] { BaseItemKind.Playlist };
}
+ else if (folder is ICollectionFolder)
+ {
+ // When the client doesn't specify recursive/includeItemTypes, force the query
+ // through the database path where all filters (IsHD, genres, etc.) are applied.
+ recursive ??= true;
+ if (includeItemTypes.Length == 0)
+ {
+ includeItemTypes = collectionType switch
+ {
+ CollectionType.boxsets => [BaseItemKind.BoxSet],
+ null => [BaseItemKind.Movie, BaseItemKind.Series],
+ _ => []
+ };
+ }
+ }
if (item is not UserRootFolder
// api keys can always access all folders
@@ -502,7 +518,7 @@ public class ItemsController : BaseJellyfinApiController
return new QueryResult<BaseItemDto>(
startIndex,
result.TotalRecordCount,
- _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user));
+ _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user, skipVisibilityCheck: true));
}
/// <summary>
@@ -598,7 +614,7 @@ public class ItemsController : BaseJellyfinApiController
[Obsolete("Kept for backwards compatibility")]
[ApiExplorerSettings(IgnoreApi = true)]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<QueryResult<BaseItemDto>> GetItemsByUserIdLegacy(
+ public async Task<ActionResult<QueryResult<BaseItemDto>>> GetItemsByUserIdLegacy(
[FromRoute] Guid userId,
[FromQuery] string? maxOfficialRating,
[FromQuery] bool? hasThemeSong,
@@ -684,7 +700,7 @@ public class ItemsController : BaseJellyfinApiController
[FromQuery, ModelBinder(typeof(CommaDelimitedCollectionModelBinder))] Guid[] genreIds,
[FromQuery] bool enableTotalRecordCount = true,
[FromQuery] bool? enableImages = true)
- => GetItems(
+ => await GetItems(
userId,
maxOfficialRating,
hasThemeSong,
@@ -770,7 +786,7 @@ public class ItemsController : BaseJellyfinApiController
studioIds,
genreIds,
enableTotalRecordCount,
- enableImages);
+ enableImages).ConfigureAwait(false);
/// <summary>
/// Gets items based on a query.