Files
mixtape/zero.Core/Search/SearchService.cs
T
2022-02-04 20:13:32 +01:00

74 lines
2.0 KiB
C#

using Raven.Client.Documents;
using Raven.Client.Documents.Queries;
using Raven.Client.Documents.Session;
namespace zero.Search;
public class SearchService : ISearchService
{
protected IZeroStore Store { get; private set; }
protected IZeroOptions Options { get; private set; }
public SearchService(IZeroStore store, IZeroOptions options)
{
Store = store;
Options = options;
}
public async Task<Paged<SearchResult>> Query(string searchTerm, int page = 1, int pageSize = 10)
{
string[] searchParts = searchTerm.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries).Select(x =>
{
return "*" + x + "*";
}).ToArray();
List<ZeroEntity> results = await Store.Session().Query<SearchIndexResult, zero_Search>()
.Statistics(out QueryStatistics stats)
.Search(x => x.Name, searchParts, 2, @operator: SearchOperator.And)
.Search(x => x.Fields, searchParts, 1, Raven.Client.Documents.SearchOptions.Or, @operator: SearchOperator.And)
.OrderByScoreDescending()
.Paging(page, pageSize)
.As<ZeroEntity>()
.ToListAsync();
List<SearchResult> items = new();
IEnumerable<SearchIndexMap> maps = Options.For<ZeroSearchOptions>();
foreach (ZeroEntity result in results)
{
Type type = result.GetType();
SearchIndexMap map = maps.FirstOrDefault(x => x.CanModify(type));
SearchResult searchResult = new()
{
Id = result.Id,
Icon = map._Icon.Or("fth-folder"),
Name = result.Name,
IsActive = result.IsActive,
Group = GetGroupName(map.Type),
Url = "/"
};
await map.Modify(result, searchResult, Options);
items.Add(searchResult);
}
return new Paged<SearchResult>(items, stats.TotalResults, 1, 20);
}
protected string GetGroupName(Type type)
{
return "@search.collection." + type.Name.ToCamelCase();
}
}
public interface ISearchService
{
Task<Paged<SearchResult>> Query(string searchTerm, int page = 1, int pageSize = 10);
}