optimize chat filtering/searching

This commit is contained in:
RaidMax 2022-06-16 18:03:23 -05:00
parent b8e001fcfe
commit fbf424c77d
10 changed files with 5072 additions and 38 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Data.Migrations.MySql
{
public partial class AddDescendingTimeSentIndexEFClientMessages : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"create index IX_EFClientMessages_TimeSentDesc on efclientmessages (TimeSent desc);");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"drop index IX_EFClientMessages_TimeSentDesc on efclientmessages;");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Data.Migrations.Postgresql
{
public partial class AddDescendingTimeSentIndexEFClientMessages : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(
@"CREATE INDEX""IX_EFClientMessages_TimeSentDesc""
ON public.""EFClientMessages"" USING btree
(""TimeSent"" DESC NULLS LAST)
TABLESPACE pg_default;"
);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"DROP INDEX public.""IX_EFClientMessages_TimeSentDesc""");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Data.Migrations.Sqlite
{
public partial class AddDescendingTimeSentIndexEFClientMessages : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@ -23,7 +23,7 @@ namespace Stats.Dtos
/// <summary> /// <summary>
/// only look for messages sent after this date /// only look for messages sent after this date
/// </summary> /// </summary>
public DateTime SentAfter { get; set; } = DateTime.UtcNow.AddYears(-100); public DateTime? SentAfter { get; set; }
/// <summary> /// <summary>
/// only look for messages sent before this date0 /// only look for messages sent before this date0

View File

@ -45,57 +45,52 @@ namespace Stats.Helpers
var result = new ResourceQueryHelperResult<MessageResponse>(); var result = new ResourceQueryHelperResult<MessageResponse>();
await using var context = _contextFactory.CreateContext(enableTracking: false); await using var context = _contextFactory.CreateContext(enableTracking: false);
if (serverCache == null) serverCache ??= await context.Set<EFServer>().ToListAsync();
{
serverCache = await context.Set<EFServer>().ToListAsync();
}
if (int.TryParse(query.ServerId, out int serverId)) if (int.TryParse(query.ServerId, out var serverId))
{ {
query.ServerId = serverCache.FirstOrDefault(_server => _server.ServerId == serverId)?.EndPoint ?? query.ServerId; query.ServerId = serverCache.FirstOrDefault(server => server.ServerId == serverId)?.EndPoint ?? query.ServerId;
} }
var iqMessages = context.Set<EFClientMessage>() var iqMessages = context.Set<EFClientMessage>()
.Where(message => message.TimeSent >= query.SentAfter)
.Where(message => message.TimeSent < query.SentBefore); .Where(message => message.TimeSent < query.SentBefore);
if (query.ClientId != null) if (query.SentAfter is not null)
{ {
iqMessages = iqMessages.Where(_message => _message.ClientId == query.ClientId.Value); iqMessages = iqMessages.Where(message => message.TimeSent >= query.SentAfter);
} }
if (query.ServerId != null) if (query.ClientId is not null)
{ {
iqMessages = iqMessages.Where(_message => _message.Server.EndPoint == query.ServerId); iqMessages = iqMessages.Where(message => message.ClientId == query.ClientId.Value);
}
if (query.ServerId is not null)
{
iqMessages = iqMessages.Where(message => message.Server.EndPoint == query.ServerId);
} }
if (!string.IsNullOrEmpty(query.MessageContains)) if (!string.IsNullOrEmpty(query.MessageContains))
{ {
iqMessages = iqMessages.Where(_message => EF.Functions.Like(_message.Message.ToLower(), $"%{query.MessageContains.ToLower()}%")); iqMessages = iqMessages.Where(message => EF.Functions.Like(message.Message.ToLower(), $"%{query.MessageContains.ToLower()}%"));
} }
var iqResponse = iqMessages var iqResponse = iqMessages
.Select(_message => new MessageResponse .Select(message => new MessageResponse
{ {
ClientId = _message.ClientId, ClientId = message.ClientId,
ClientName = query.IsProfileMeta ? "" : _message.Client.CurrentAlias.Name, ClientName = query.IsProfileMeta ? "" : message.Client.CurrentAlias.Name,
ServerId = _message.ServerId, ServerId = message.ServerId,
When = _message.TimeSent, When = message.TimeSent,
Message = _message.Message, Message = message.Message,
ServerName = query.IsProfileMeta ? "" : _message.Server.HostName, ServerName = query.IsProfileMeta ? "" : message.Server.HostName,
GameName = _message.Server.GameName == null ? Server.Game.IW4 : (Server.Game)_message.Server.GameName.Value, GameName = message.Server.GameName == null ? Server.Game.IW4 : (Server.Game)message.Server.GameName.Value,
SentIngame = _message.SentIngame SentIngame = message.SentIngame
}); });
if (query.Direction == SharedLibraryCore.Dtos.SortDirection.Descending) iqResponse = query.Direction == SharedLibraryCore.Dtos.SortDirection.Descending
{ ? iqResponse.OrderByDescending(message => message.When)
iqResponse = iqResponse.OrderByDescending(_message => _message.When); : iqResponse.OrderBy(message => message.When);
}
else
{
iqResponse = iqResponse.OrderBy(_message => _message.When);
}
var resultList = await iqResponse var resultList = await iqResponse
.Skip(query.Offset) .Skip(query.Offset)
@ -115,13 +110,13 @@ namespace Stats.Helpers
{ {
var quickMessages = _defaultSettings var quickMessages = _defaultSettings
.QuickMessages .QuickMessages
.First(_qm => _qm.Game == message.GameName); .First(qm => qm.Game == message.GameName);
message.Message = quickMessages.Messages[message.Message.Substring(1)]; message.Message = quickMessages.Messages[message.Message.Substring(1)];
message.IsQuickMessage = true; message.IsQuickMessage = true;
} }
catch catch
{ {
message.Message = message.Message.Substring(1); message.Message = message.Message[1..];
} }
} }

View File

@ -4,7 +4,7 @@
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<PackageId>RaidMax.IW4MAdmin.SharedLibraryCore</PackageId> <PackageId>RaidMax.IW4MAdmin.SharedLibraryCore</PackageId>
<Version>2022.6.15.1</Version> <Version>2022.6.16.1</Version>
<Authors>RaidMax</Authors> <Authors>RaidMax</Authors>
<Company>Forever None</Company> <Company>Forever None</Company>
<Configurations>Debug;Release;Prerelease</Configurations> <Configurations>Debug;Release;Prerelease</Configurations>
@ -19,7 +19,7 @@
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>
<Description>Shared Library for IW4MAdmin</Description> <Description>Shared Library for IW4MAdmin</Description>
<PackageVersion>2022.6.15.1</PackageVersion> <PackageVersion>2022.6.16.1</PackageVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn> <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup> </PropertyGroup>

View File

@ -13,7 +13,9 @@
<div class="align-self-center "> <div class="align-self-center ">
<a asp-controller="Client" asp-action="Profile" asp-route-id="@ban.ClientId" class="font-size-18 no-decoration">@ban.ClientName</a> <a asp-controller="Client" asp-action="Profile" asp-route-id="@ban.ClientId" class="font-size-18 no-decoration">@ban.ClientName</a>
<br/> <br/>
<div data-toggle="tooltip" data-title="@ViewBag.Localization[$"GAME_{ban.Game}"]">
<div class="badge">@Utilities.MakeAbbreviation(ViewBag.Localization[$"GAME_{ban.Game}"])</div> <div class="badge">@Utilities.MakeAbbreviation(ViewBag.Localization[$"GAME_{ban.Game}"])</div>
</div>
<has-permission entity="ClientGuid" required-permission="Read"> <has-permission entity="ClientGuid" required-permission="Read">
<div class="text-muted">@ban.NetworkId.ToString("X")</div> <div class="text-muted">@ban.NetworkId.ToString("X")</div>
</has-permission> </has-permission>
@ -47,6 +49,10 @@
<a asp-controller="Client" asp-action="Profile" asp-route-id="@associatedEntity.OffenderInfo.ClientId" class="font-size-18 no-decoration">@associatedEntity.OffenderInfo.ClientName</a> <a asp-controller="Client" asp-action="Profile" asp-route-id="@associatedEntity.OffenderInfo.ClientId" class="font-size-18 no-decoration">@associatedEntity.OffenderInfo.ClientName</a>
</div> </div>
</div> </div>
<div data-toggle="tooltip" data-title="@ViewBag.Localization[$"GAME_{ban.Game}"]">
<div class="badge">@Utilities.MakeAbbreviation(ViewBag.Localization[$"GAME_{ban.Game}"])</div>
</div>
<br/>
<has-permission entity="ClientGuid" required-permission="Read"> <has-permission entity="ClientGuid" required-permission="Read">
<div class="text-muted">@associatedEntity.OffenderInfo.NetworkId?.ToString("X")</div> <div class="text-muted">@associatedEntity.OffenderInfo.NetworkId?.ToString("X")</div>
</has-permission> </has-permission>
@ -57,7 +63,6 @@
<div class="text-muted font-weight-light">@associatedEntity.Offense.CapClientName(30)</div> <div class="text-muted font-weight-light">@associatedEntity.Offense.CapClientName(30)</div>
<div class="text-danger font-weight-light">@associatedEntity.DateTime.ToStandardFormat()</div> <div class="text-danger font-weight-light">@associatedEntity.DateTime.ToStandardFormat()</div>
<div class="btn profile-action mt-10 w-100" data-action="unban" data-action-id="@associatedEntity.OffenderInfo.ClientId">Unban</div> <div class="btn profile-action mt-10 w-100" data-action="unban" data-action-id="@associatedEntity.OffenderInfo.ClientId">Unban</div>
<div class="badge">@Utilities.MakeAbbreviation(ViewBag.Localization[$"GAME_{ban.Game}"])</div>
</div> </div>
} }
</div> </div>