summaryrefslogtreecommitdiff
path: root/Services/SearchService.cs
blob: e8e497d6263b7f52ee68093ac8b260ed6e7856ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using Microsoft.EntityFrameworkCore;

namespace HyperBooru.Services;

public interface ISearchService {
    public Media[] Search(string query);
}

public class SearchService : ISearchService {
    private ITagService tagService;

    private IDbContextFactory<HBContext> dbFactory;

    public SearchService(
        IDbContextFactory<HBContext> 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();
    }
}