using Microsoft.EntityFrameworkCore; namespace HyperBooru.Services; public interface ISearchService { public Media[] Search(string query); } public class SearchService : ISearchService { private ITagService tagService; private IDbContextFactory dbFactory; public SearchService( IDbContextFactory dbFactory, ITagService tagService) { this.tagService = tagService; this.dbFactory = dbFactory; } public Media[] Search(string query) { var db = dbFactory.CreateDbContext(); query = query.ToLower(); var matchedTag = db.TagDefinitions .FirstOrDefault(td => td.Name.ToLower() == query); int[] tags; if(matchedTag is not null) { tags = tagService .TagsThatImply(matchedTag) .Select(td => td.ObjectId) .ToArray(); } else { // TODO: expand scope to all tags that imply tags = db.TagDefinitions .Where(td => td.Name.ToLower().Contains(query)) .Select(td => td.ObjectId) .ToArray(); } return db.Media .Include(m => m.Tags) .AsEnumerable() .Where(m => m.Tags.IntersectBy(tags, t => t.TagDefinitionId).Any()) .Concat(db.Media .Where(m => (m.ShortDescription != null && m.ShortDescription.ToLower().Contains(query)) || (m.LongDescription != null && m.LongDescription.ToLower().Contains(query)))) .DistinctBy(m => m.ObjectId) .ToArray(); } }