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) && q.Term(f => f.IsDeleted, false) ) ); 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) ); 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.TraceTimeZone) )) .Query(q => q.Terms(t => t .Field(f => f.OrderNo.Suffix("keyword")) .Terms(orderNos)) && q.Term(f => f.OrderType, orderType) && q.Term(t => t.Field(f => f.IsDeleted).Value(false)) ) ); return data.Documents.ToList(); } 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 DeleteTrackAsync(int orderId, List trackCodes) { var r = await Context.UpdateByQueryAsync(x => x .Query( q => q.Term(t => t.OrderId, orderId) && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) .Script(s => s .Source("ctx._source.isDeleted = true")) ); if (!r.IsValid) throw new Exception($"轨迹数据删除失败,原因:{r.DebugInformation}"); } 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)) && q.Term(t => t.Field(f => f.IsDeleted).Value(false)) ) .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); } }