using Nest; using SJZY.Expand.ABP.Core.Logger; using SJZY.Expand.ElasticSearch.Services; using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate; using SJZY.Track.Domain.Dtos.TrackDetails; namespace SJZY.Track.Repository.Repositories; internal class TrackDetailsRepository : ElasticSearchContextAbstract, ITrackDetailsRepository, ITransientDependency { public TrackDetailsRepository(ConnectionFactory connectionFactory) : base(connectionFactory) { } public async Task GetFirstOrDefaultAsync(int orderId, string trackCode) { var r = await Context.SearchAsync(s => s .Source() .Query(q => q.Term(f => f.OrderId, orderId) && q.Term(f => f.TrackCode.Suffix("keyword"), trackCode) ) ); var res = r.Documents.FirstOrDefault(); if (res != default && r.Hits.FirstOrDefault() != default) { res.Id = r.Hits.FirstOrDefault()!.Id; } return res; } public async Task UpsertAsync(TrackDetailsIndex index) { if (index.Id.IsNullOrWhiteSpace()) { // 按天写入es var r = await Context.IndexAsync(index, request => request .Index(index.IndexName) //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 ); if (!r.IsValid) { LogHelper.Error($"轨迹新增失败,原因:{r.DebugInformation}。"); } } else { var r = await Context.UpdateAsync(index.Id, u => u .Index(index.IndexName) .Doc(index) //.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见 ); if (!r.IsValid) { LogHelper.Error($"轨迹更新失败,原因:{r.DebugInformation}。"); } } } public async Task> GetListAsync(int orderType, List orderNos) { if (orderNos.Count < 1) return new List(); var data = await Context.SearchAsync(x => x .Source(s => s.Includes(fd => fd .Field(f => f.OrderNo) .Field(f => f.TrackStatus) .Field(f => f.TrackCode) .Field(f => f.TrackContent) .Field(f => f.TrackPlace) .Field(f => f.TrackTime) .Field(f => f.TrackTimeZone) )) .Query(q => q.Terms(t => t .Field(f => f.OrderNo.Suffix("keyword")) .Terms(orderNos)) && q.Term(f => f.OrderType, orderType) ) ); return data.Documents.ToList(); } public Task> GetListAsync(int orderType, List orderNos, string trackCode) { throw new NotImplementedException(); } public async Task> GetListAsync(int orderId) { var data = await Context.SearchAsync(x => x .Query(q => q.Term(t => t.OrderId, orderId) ) .Size(1000) .Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending))); return data.Documents.ToList(); } public async Task?> GetListAsync(List orderIds) { var data = await Context.SearchAsync(x => x.Query(q => q.Terms(t => t.Field(g => g.OrderId).Terms(orderIds)) ) .Size(10000) .Sort(s => s.Field(c => c.TrackTime, SortOrder.Descending)) ); return data?.Documents?.ToList(); } public async Task GetLatestAsync(int orderId) { var data = await Context.SearchAsync(x => x .Source(s => s.Includes(fd => fd .Field(f => f.IsCompleted) .Field(f => f.TrackEnContent) .Field(f => f.TrackContent) .Field(f => f.TrackPlace) .Field(f => f.TrackTime) .Field(f => f.TrackTimeZone) )) .Query(q => q.Term(f => f.OrderId, orderId) ) .Sort(s => s.Field(f => f.TrackTime, SortOrder.Descending)) .Size(1) ); return data.Documents.FirstOrDefault(); } public async Task DeleteTrackAsync(int orderId, List trackCodes) { var r = await Context.DeleteByQueryAsync(x => x .Query( q => q.Term(t => t.OrderId, orderId) && q.Term(t => t.IsCanDelete, true) && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) .Refresh() // 可选:立即刷新索引使更改立即可见 ); if (!r.IsValid) throw new Exception($"轨迹数据删除失败,原因:{r.DebugInformation}"); return r.Deleted > 0; } public async Task<(List list, long total)> GetListAsync(TrackDetailsQueryInput input) { if (input.OrderNos.Count < 1) return default; var distinctOrderNumbers = input.OrderNos.Distinct(); var finalSize = input.PageSize > 500 ? 500 : input.PageSize; var data = await Context.SearchAsync(x => x .Query(q => q.Terms(t => t .Field(f => f.OrderNo) .Terms(distinctOrderNumbers)) ) .Sort(s => s.Field(f => f.CreateTime, SortOrder.Descending)) .From((input.PageIndex - 1) * input.PageSize) .Size(finalSize) .TrackTotalHits() // todo: 聚合获取匹配查询条件的文档总数,而不受"index.max_result_window"的限制 ); return (data.Documents.ToList(), data.Total); } }