// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschraenkt) // All rights reserved. Licensed under the MIT license. // ========================================================================== using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MongoDB.Driver; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Infrastructure; using Squidex.Infrastructure.MongoDb.Queries; using Squidex.Infrastructure.Queries; namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations { internal sealed class QueryByIds : OperationBase { public QueryByIds(DataConverter dataConverter) : base(dataConverter) { } public async Task> QueryIdsAsync(DomainId appId, HashSet ids) { if (ids == null || ids.Count == 0) { return new List<(DomainId SchemaId, DomainId Id, Status Status)>(); } var filter = CreateFilter(appId, null, ids); var contentItems = await Collection.FindStatusAsync(filter); return contentItems.Select(x => (x.IndexedSchemaId, x.Id, x.Status)).ToList(); } public async Task> QueryAsync(DomainId appId, List schemas, Q q) { Guard.NotNull(q, nameof(q)); if (q.Ids == null || q.Ids.Count == 0) { return ResultList.CreateFrom(0); } var filter = CreateFilter(appId, schemas.Select(x => x.Id), q.Ids.ToHashSet()); var contentEntities = await FindContentsAsync(q.Query, filter); var contentTotal = (long)contentEntities.Count; if (contentEntities.Count > 0) { if (contentTotal >= q.Query.Take || q.Query.Skip > 0) { contentTotal = await Collection.Find(filter).CountDocumentsAsync(); } var contentSchemas = schemas.ToDictionary(x => x.Id); foreach (var content in contentEntities) { var schema = contentSchemas[content.SchemaId.Id]; content.ParseData(schema.SchemaDef, DataConverter); } } return ResultList.Create(contentTotal, contentEntities); } private async Task> FindContentsAsync(ClrQuery query, FilterDefinition filter) { var result = Collection.Find(filter) .QueryLimit(query) .QuerySkip(query) .ToListAsync(); return await result; } private static FilterDefinition CreateFilter(DomainId appId, IEnumerable? schemaIds, HashSet ids) { var filters = new List>(); var documentIds = ids.Select(x => DomainId.Combine(appId, x)).ToList(); if (documentIds.Count > 1) { filters.Add( Filter.Or( Filter.In(x => x.DocumentId, documentIds))); } else { var first = documentIds.First(); filters.Add( Filter.Or( Filter.Eq(x => x.DocumentId, first))); } if (schemaIds != null) { filters.Add(Filter.In(x => x.IndexedSchemaId, schemaIds)); } filters.Add(Filter.Ne(x => x.IsDeleted, true)); return Filter.And(filters); } } }