public virtual IQueryable <Subscriber <long> > CreateSelectQuery(SubscriptionParameters parameters , SubscribersRangeParameters <long> subscribersRange, SenderDbContext context) { IQueryable <SubscriberDeliveryTypeSettingsLong> query = CreateDeliveryTypeSelectQuery(parameters, subscribersRange, context); if (subscribersRange.SelectFromCategories) { IQueryable <SubscriberCategorySettingsLong> categoryQueryPart = CreateCategorySelectQuery(parameters, subscribersRange, context); query = JoinWithCategoriesSelect(parameters, query, categoryQueryPart); } if (subscribersRange.SelectFromTopics) { IQueryable <SubscriberTopicSettingsLong> topicQueryPart = CreateTopicSelectQuery(parameters, subscribersRange, context); query = JoinWithTopicsSelect(parameters, subscribersRange, query, topicQueryPart); } IQueryable <Subscriber <long> > subscribers = query.Select(d => new Subscriber <long> { SubscriberId = d.SubscriberId, DeliveryType = d.DeliveryType, Address = d.Address, TimeZoneId = d.TimeZoneId, Language = d.Language }); if (subscribersRange.Limit != null) { subscribers = subscribers.Take(subscribersRange.Limit.Value); } return(subscribers); }
protected override void When() { _expectedSubscribers = SubscribersGenerated .GetList <SubscriberWithMissingData>() .Where(x => x.HasAddress && x.HasTopicsSettingsEnabled) .TakeLast(10) .ToList(); var subscribersRange = new SubscribersRangeParameters <ObjectId>() { SelectFromTopics = true, TopicId = _topicId, SubscriberIdRangeFromIncludingSelf = _expectedSubscribers.First().SubscriberId, SubscriberIdRangeToIncludingSelf = _expectedSubscribers.Last().SubscriberId }; var subscriberParameters = new SubscriptionParameters() { DeliveryType = _deliveryType, CategoryId = _categoryId, TopicId = _topicId, CheckTopicEnabled = true, }; _actualSubscribers = SUT.Select(subscriberParameters, subscribersRange).Result; }
protected override void When() { _expectedSubscribers = SubscribersGenerated .GetList <SubscriberWithMissingData>() .Where(x => x.HasAddress && x.HasCategorySettingsEnabled) .TakeLast(10) .ToList(); var subscribersRange = new SubscribersRangeParameters <ObjectId>() { SelectFromCategories = true, SubscriberIdRangeFromIncludingSelf = _expectedSubscribers.First().SubscriberId, SubscriberIdRangeToIncludingSelf = _expectedSubscribers.Last().SubscriberId }; var subscriberParameters = new SubscriptionParameters() { DeliveryType = _deliveryType, CategoryId = _categoryId, CheckCategoryEnabled = true }; _queryDurationWatch = Stopwatch.StartNew(); _actualSubscribers = SUT.Select(subscriberParameters, subscribersRange).Result; _queryDurationWatch.Stop(); }
protected virtual string ToCategorySettingsLookupFilter(SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange, bool joinOnCategories) { string subscriberIdField = FieldDefinitions.GetFieldMappedName <TCategory>(x => x.SubscriberId); string deliveryTypeField = FieldDefinitions.GetFieldMappedName <TCategory>(x => x.DeliveryType); string categoryField = FieldDefinitions.GetFieldMappedName <TCategory>(x => x.CategoryId); string categoriesJoinCondition = joinOnCategories ? $", $eq: [\"${categoryField}\", \"$$category_id\"]" : ""; var categoryFilter = ToCategorySettingsFilter(parameters, subscribersRange); string categoryFilterJson = categoryFilter.RenderJson(); return($@"""$and"": [ {{ ""$expr"": {{ $and: [ {{ $eq: [""${ subscriberIdField }"", ""$$subscriber_id""] }}, {{ $eq: [""${ deliveryTypeField }"", ""$$delivery_type""] }} {categoriesJoinCondition} ] }} }}, {categoryFilterJson} ]"); }
//method public virtual EventHandleResult <Subscriber <TKey> > Select(EventSettings <TKey> eventSettings, SignalEvent <TKey> signalEvent) { if (signalEvent.AddresseeType == AddresseeType.DirectAddresses) { return(ConvertAddressesToSubscribers(eventSettings, signalEvent)); } if (signalEvent.AddresseeType == AddresseeType.SubscriberIds) { var subscribersRange = new SubscribersRangeParameters <TKey>() { FromSubscriberIds = signalEvent.PredefinedSubscriberIds }; return(QuerySubscribers(eventSettings, signalEvent, subscribersRange)); } if (signalEvent.AddresseeType == AddresseeType.SubscriptionParameters) { var subscribersRange = new SubscribersRangeParameters <TKey>() { SubscriberIdRangeFromIncludingSelf = signalEvent.SubscriberIdRangeFrom, SubscriberIdRangeToIncludingSelf = signalEvent.SubscriberIdRangeTo, SubscriberIdFromDeliveryTypesHandled = signalEvent.SubscriberIdFromDeliveryTypesHandled, Limit = ItemsQueryLimit }; return(QuerySubscribers(eventSettings, signalEvent, subscribersRange)); } string message = string.Format(SenderInternalMessages.SubscribersFetcher_UnknownAddresseeType , signalEvent.AddresseeType, signalEvent.GetType()); throw new NotImplementedException(message); }
protected virtual IQueryable <SubscriberDeliveryTypeSettingsLong> CreateDeliveryTypeSelectQuery( SubscriptionParameters parameters, SubscribersRangeParameters <long> subscribersRange, SenderDbContext context) { IQueryable <SubscriberDeliveryTypeSettingsLong> query = context.SubscriberDeliveryTypeSettings .Where(p => p.Address != null); if (subscribersRange.FromSubscriberIds != null) { query = query.Where(p => subscribersRange.FromSubscriberIds.Contains(p.SubscriberId)); } if (subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { query = query.Where(p => subscribersRange.SubscriberIdRangeFromIncludingSelf.Value <= p.SubscriberId); } if (subscribersRange.SubscriberIdRangeToIncludingSelf != null) { query = query.Where(p => p.SubscriberId <= subscribersRange.SubscriberIdRangeToIncludingSelf.Value); } if (subscribersRange.SubscriberIdFromDeliveryTypesHandled != null && subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { query = query.Where( p => p.SubscriberId != subscribersRange.SubscriberIdRangeToIncludingSelf.Value || (p.SubscriberId == subscribersRange.SubscriberIdRangeToIncludingSelf.Value && !subscribersRange.SubscriberIdFromDeliveryTypesHandled.Contains(p.DeliveryType)) ); } if (parameters.DeliveryType != null) { query = query.Where(p => p.DeliveryType == parameters.DeliveryType.Value); } if (parameters.CheckDeliveryTypeEnabled) { query = query.Where(p => p.IsEnabled == true); } if (parameters.CheckDeliveryTypeLastSendDate) { query = query.Where(p => p.LastSendDateUtc == null || (p.LastVisitUtc != null && p.LastSendDateUtc < p.LastVisitUtc)); } if (parameters.CheckDeliveryTypeSendCountNotGreater != null) { int sendCountLimitValue = parameters.CheckDeliveryTypeSendCountNotGreater.Value; query = query.Where(p => p.SendCount <= sendCountLimitValue); } if (parameters.CheckIsNDRBlocked) { query = query.Where(p => p.IsNDRBlocked == false); } return(query); }
protected virtual FilterDefinition <TCategory> ToCategorySettingsFilter( SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { var filter = Builders <TCategory> .Filter.Where(p => true); if (parameters.DeliveryType != null) { filter &= Builders <TCategory> .Filter.Where( p => p.DeliveryType == parameters.DeliveryType.Value); } if (parameters.CategoryId != null) { filter &= Builders <TCategory> .Filter.Where( p => p.CategoryId == parameters.CategoryId); } if (parameters.CheckCategoryEnabled) { filter &= Builders <TCategory> .Filter.Where(p => p.IsEnabled == true); } if (parameters.CheckCategorySendCountNotGreater != null) { filter &= Builders <TCategory> .Filter.Where( p => p.SendCount <= parameters.CheckCategorySendCountNotGreater.Value); } if (subscribersRange.FromSubscriberIds != null) { filter &= Builders <TCategory> .Filter.Where( p => subscribersRange.FromSubscriberIds.Contains(p.SubscriberId)); } if (subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { filter &= Builders <TCategory> .Filter.Where( p => subscribersRange.SubscriberIdRangeFromIncludingSelf.Value <= p.SubscriberId); } if (subscribersRange.SubscriberIdRangeToIncludingSelf != null) { filter &= Builders <TCategory> .Filter.Where( p => p.SubscriberId <= subscribersRange.SubscriberIdRangeToIncludingSelf.Value); } if (subscribersRange.SubscriberIdFromDeliveryTypesHandled != null && subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { filter &= Builders <TCategory> .Filter.Where( p => p.SubscriberId != subscribersRange.SubscriberIdRangeToIncludingSelf.Value || (p.SubscriberId == subscribersRange.SubscriberIdRangeToIncludingSelf.Value && !subscribersRange.SubscriberIdFromDeliveryTypesHandled.Contains(p.DeliveryType))); } return(filter); }
protected virtual PipelineDefinition <TInput, BsonDocument> AddCategoryLookupStages <TInput>( PipelineDefinition <TInput, BsonDocument> pipeline, SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { if (!subscribersRange.SelectFromCategories) { return(pipeline); } string categoryCollection = _collectionFactory.GetCollection <TCategory>().CollectionNamespace.CollectionName; string subscriberIdField = subscribersRange.SelectFromTopics ? FieldDefinitions.GetFieldMappedName <TTopic>(x => x.SubscriberId) : FieldDefinitions.GetFieldMappedName <TDeliveryType>(x => x.SubscriberId); string deliveryTypeField = subscribersRange.SelectFromTopics ? FieldDefinitions.GetFieldMappedName <TTopic>(x => x.DeliveryType) : FieldDefinitions.GetFieldMappedName <TDeliveryType>(x => x.DeliveryType); string categoryField = FieldDefinitions.GetFieldMappedName <TTopic>(x => x.CategoryId); string categoriesIntermediateField = "cats"; bool joinOnCategories = subscribersRange.SelectFromTopics; string joinOnCategory = joinOnCategories ? $", category_id: \"{categoryField}\"" : ""; string matchConditions = ToCategorySettingsLookupFilter(parameters, subscribersRange, joinOnCategories); string categoriesLookup = $@" {{ $lookup : {{ from: ""{categoryCollection}"", let: {{ subscriber_id: ""${subscriberIdField}"", delivery_type: ""${deliveryTypeField}"" {joinOnCategory} }}, pipeline: [ {{ $match: {{ {matchConditions} }} }}, {{ $project: {{ _id: 1 }} }} ], as: ""{categoriesIntermediateField}"" }} }}"; string hasCategoriesStage = $@" {{ $match: {{ {categoriesIntermediateField}: {{ $exists: true, $ne: [] }} }} }}"; return(pipeline .AppendStage(categoriesLookup, BsonDocumentSerializer.Instance) .AppendStage(hasCategoriesStage, BsonDocumentSerializer.Instance)); }
//Select with join public virtual Task <List <Subscriber <ObjectId> > > Select( SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { if (subscribersRange.SelectFromTopics) { return(LookupStartingWithTopics(parameters, subscribersRange)); } else { return(LookupStartingWithDeliveryTypes(parameters, subscribersRange)); } }
protected virtual IQueryable <SubscriberCategorySettingsLong> CreateCategorySelectQuery( SubscriptionParameters parameters, SubscribersRangeParameters <long> subscribersRange, SenderDbContext context) { IQueryable <SubscriberCategorySettingsLong> query = context.SubscriberCategorySettings; if (parameters.CategoryId != null) { query = query.Where(p => p.CategoryId == parameters.CategoryId); } if (parameters.DeliveryType != null) { query = query.Where(p => p.DeliveryType == parameters.DeliveryType.Value); } if (subscribersRange.FromSubscriberIds != null) { query = query.Where(p => subscribersRange.FromSubscriberIds.Contains(p.SubscriberId)); } if (subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { query = query.Where(p => subscribersRange.SubscriberIdRangeFromIncludingSelf.Value <= p.SubscriberId); } if (subscribersRange.SubscriberIdRangeToIncludingSelf != null) { query = query.Where(p => p.SubscriberId <= subscribersRange.SubscriberIdRangeToIncludingSelf.Value); } if (subscribersRange.SubscriberIdFromDeliveryTypesHandled != null && subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { query = query.Where( p => p.SubscriberId != subscribersRange.SubscriberIdRangeToIncludingSelf.Value || (p.SubscriberId == subscribersRange.SubscriberIdRangeToIncludingSelf.Value && !subscribersRange.SubscriberIdFromDeliveryTypesHandled.Contains(p.DeliveryType)) ); } if (parameters.CheckCategoryEnabled) { query = query.Where(p => p.IsEnabled == true); } if (parameters.CheckCategorySendCountNotGreater != null) { int sendCountLimitValue = parameters.CheckCategorySendCountNotGreater.Value; query = query.Where(p => p.SendCount <= sendCountLimitValue); } return(query); }
//filters public override FilterDefinition <TDeliveryType> ToDeliveryTypeSettingsFilter( SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { var filter = base.ToDeliveryTypeSettingsFilter(parameters, subscribersRange); if (subscribersRange.SelectFromCategories) { var categoriesFilter = ToCategorySettingsFilter(parameters, subscribersRange); filter &= Builders <TDeliveryType> .Filter .ElemMatch(x => x.SubscriberCategorySettings, categoriesFilter); } return(filter); }
protected virtual FilterDefinition <TTopic> ToTopicSettingsFilter( SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { var filter = Builders <TTopic> .Filter.Where( p => p.TopicId == subscribersRange.TopicId && p.IsDeleted == false); if (parameters.DeliveryType != null) { filter &= Builders <TTopic> .Filter.Where( p => p.DeliveryType == parameters.DeliveryType.Value); } if (parameters.CategoryId != null) { filter &= Builders <TTopic> .Filter.Where( p => p.CategoryId == parameters.CategoryId); } if (parameters.CheckTopicEnabled) { filter &= Builders <TTopic> .Filter.Where(p => p.IsEnabled); } if (parameters.CheckTopicSendCountNotGreater != null) { filter = Builders <TTopic> .Filter.Where( p => p.SendCount <= parameters.CheckTopicSendCountNotGreater.Value); } if (subscribersRange.FromSubscriberIds != null) { filter &= Builders <TTopic> .Filter.Where( p => subscribersRange.FromSubscriberIds.Contains(p.SubscriberId)); } if (subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { filter &= Builders <TTopic> .Filter.Where( p => subscribersRange.SubscriberIdRangeFromIncludingSelf.Value <= p.SubscriberId); } if (subscribersRange.SubscriberIdRangeToIncludingSelf != null) { filter &= Builders <TTopic> .Filter.Where( p => p.SubscriberId <= subscribersRange.SubscriberIdRangeToIncludingSelf.Value); } return(filter); }
//select public virtual async Task <List <Subscriber <long> > > Select( SubscriptionParameters parameters, SubscribersRangeParameters <long> subscribersRange) { List <Subscriber <long> > subscribers = null; using (var context = _dbContextFactory.GetDbContext()) { IQueryable <Subscriber <long> > query = CreateSelectQuery(parameters, subscribersRange, context); subscribers = await query.ToListAsync().ConfigureAwait(false); } return(subscribers); }
protected override void When() { var subscriberParameters = new SubscriptionParameters() { DeliveryType = _deliveryType, CategoryId = _categoryId, TopicId = _topicId, CheckTopicEnabled = true, }; var subscribersRange = new SubscribersRangeParameters <ObjectId>() { SelectFromTopics = true, TopicId = _topicId }; _actualSubscribers = SUT.Select(subscriberParameters, subscribersRange).Result; }
protected virtual EventHandleResult <Subscriber <TKey> > QuerySubscribers( EventSettings <TKey> eventSettings, SignalEvent <TKey> signalEvent, SubscribersRangeParameters <TKey> rangeParameters) { if (eventSettings.Subscription == null) { _logger.LogError(SenderInternalMessages.Common_ParameterMissing, nameof(eventSettings.Subscription)); return(EventHandleResult <Subscriber <TKey> > .FromResult(ProcessingResult.Fail)); } //use TopicId from SignalEvent over default one in EventSettings //if both are null will not query for topic rangeParameters.TopicId = signalEvent.TopicId ?? eventSettings.Subscription.TopicId; //overwrite Subscription filters data with SignalEvent filters data rangeParameters.SubscriberFilters = new Dictionary <string, string>(); rangeParameters.SubscriberFilters.Merge(eventSettings.Subscription.SubscriberFiltersData); rangeParameters.SubscriberFilters.Merge(signalEvent.SubscriberFiltersData); bool categoryParameterChecked = eventSettings.Subscription.CheckCategoryLastSendDate || eventSettings.Subscription.CheckCategoryEnabled || eventSettings.Subscription.CheckCategorySendCountNotGreater != null; rangeParameters.SelectFromCategories = eventSettings.Subscription.CategoryId != null && categoryParameterChecked; bool topicParameterChecked = eventSettings.Subscription.CheckTopicLastSendDate || eventSettings.Subscription.CheckTopicEnabled || eventSettings.Subscription.CheckTopicSendCountNotGreater != null; //if delivery type is not specified, will look for topic settings for all delivery types rangeParameters.SelectFromTopics = eventSettings.Subscription.CategoryId != null && rangeParameters.TopicId != null && topicParameterChecked; List <Subscriber <TKey> > subscribers = _subscriberQueries .Select(eventSettings.Subscription, rangeParameters).Result; return(new EventHandleResult <Subscriber <TKey> >() { Items = subscribers, IsFinished = subscribers.Count < rangeParameters.Limit, Result = ProcessingResult.Success }); }
protected override void When() { var subscriberParameters = new SubscriptionParameters() { DeliveryType = _deliveryType, CategoryId = _categoryId, CheckCategoryEnabled = true }; var subscribersRange = new SubscribersRangeParameters <ObjectId>() { SelectFromCategories = true, }; int totalMatchingCount = SubscribersGenerated.GetList <SubscriberWithMissingData>() .Where(x => x.HasAddress && x.HasCategorySettingsEnabled) .Count(); _actualSubscribers = SUT.Select(subscriberParameters, subscribersRange).Result; }
protected override void When() { _subscribersWithEmptyAddressToQuery = SubscribersGenerated.GetList <SubscriberWithMissingData>() .Where(x => !x.HasAddress) .Take(5) .Select(x => x.SubscriberId) .ToList(); var subscriberParameters = new SubscriptionParameters() { DeliveryType = _deliveryType }; var subscribersRange = new SubscribersRangeParameters <ObjectId>() { FromSubscriberIds = _subscribersWithEmptyAddressToQuery }; _actualSubscribers = SUT.Select(subscriberParameters, subscribersRange).Result; }
protected override void When() { var subscriberParameters = new SubscriptionParameters() { DeliveryType = _deliveryType, CategoryId = _categoryId, TopicId = _topicId, CheckIsNDRBlocked = true, CheckCategoryEnabled = true, CheckTopicEnabled = true, CheckDeliveryTypeEnabled = true }; var subscribersRange = new SubscribersRangeParameters <long>() { FromSubscriberIds = _subscriberIds }; _matchedSubscribers = SUT.Select(subscriberParameters, subscribersRange).Result; }
//subscribers selection protected override Task <List <Subscriber <ObjectId> > > LookupStartingWithDeliveryTypes( SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { var pipeline = new EmptyPipelineDefinition <TDeliveryType>() .As <TDeliveryType, TDeliveryType, TDeliveryType>(); var pipeline2 = pipeline.Match(ToDeliveryTypeSettingsFilter(parameters, subscribersRange)) .As <TDeliveryType, TDeliveryType, BsonDocument>(); //var bsonDocs = _context.SubscriberDeliveryTypeSettings.Aggregate(pipeline2).ToListAsync(); //string json = subscribers.Select(x => x.ToJsonIntended()).Join(","); //return null; PipelineDefinition <TDeliveryType, Subscriber <ObjectId> > pipelineProjected = AddSubscribersProjectionAndLimitStage(pipeline2, subscribersRange); return(_collectionFactory .GetCollection <TDeliveryType>() .Aggregate(pipelineProjected) .ToListAsync()); }
protected virtual string ToDeliveryTypeSettingsLookupFilter( SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { string deliveryTypeField = FieldDefinitions.GetFieldMappedName <TDeliveryType>(x => x.DeliveryType); string subscriberIdField = FieldDefinitions.GetFieldMappedName <TDeliveryType>(x => x.SubscriberId); var deliveryTypesFilter = ToDeliveryTypeSettingsFilter(parameters, subscribersRange); string deliveryTypesFilterJson = deliveryTypesFilter.RenderJson(); return($@"""$and"": [ {{ ""$expr"": {{ $and: [ {{ $eq: [""${subscriberIdField}"", ""$$subscriber_id""] }}, {{ $eq: [""${deliveryTypeField}"", ""$$delivery_type""] }} ] }} }}, {deliveryTypesFilterJson} ]"); }
//methods protected override void When() { var subscribersRange = new SubscribersRangeParameters <ObjectId>() { SelectFromTopics = true, TopicId = _topicId, SubscriberIdRangeFromIncludingSelf = new ObjectId("5e62aec745e7c56d244a4de0"), SubscriberIdRangeToIncludingSelf = new ObjectId("5e62aec745e7c56d244a4de1") }; var subscriberParameters = new SubscriptionParameters() { DeliveryType = _deliveryType, CategoryId = _categoryId, TopicId = _topicId, CheckTopicEnabled = true, }; var deliveryTypefilterDefinition = SUT.ToDeliveryTypeSettingsFilter(subscriberParameters, subscribersRange); _actualJson = deliveryTypefilterDefinition.RenderJson(); }
protected virtual PipelineDefinition <TInput, Subscriber <ObjectId> > AddSubscribersProjectionAndLimitStage <TInput>( PipelineDefinition <TInput, BsonDocument> pipeline, SubscribersRangeParameters <ObjectId> subscribersRange) { var projection = Builders <TDeliveryType> .Projection .Exclude(x => x.SubscriberDeliveryTypeSettingsId) .Include(x => x.SubscriberId) .Include(x => x.DeliveryType) .Include(x => x.Address) .Include(x => x.TimeZoneId) .Include(x => x.Language); var pipelineTyped = pipeline .As <TInput, BsonDocument, TDeliveryType>() .Project(projection) .As <TInput, BsonDocument, Subscriber <ObjectId> >(); if (subscribersRange.Limit != null) { pipelineTyped = pipelineTyped.Limit(subscribersRange.Limit.Value); } return(pipelineTyped); }
protected override void When() { _subscribersWithTopicLastSendDate = SubscribersGenerated.GetList <SubscriberWithMissingData>() .Where(x => x.HasTopicLastSendDate) .Select(x => x.SubscriberId) .ToList(); var subscriberParameters = new SubscriptionParameters() { DeliveryType = _deliveryType, CategoryId = _categoryId, CheckTopicLastSendDate = true }; var subscribersRange = new SubscribersRangeParameters <ObjectId>() { SelectFromTopics = true, TopicId = _topicId, FromSubscriberIds = _subscribersWithTopicLastSendDate }; _actualSubscribers = SUT.Select(subscriberParameters, subscribersRange).Result; }
protected virtual Task <List <Subscriber <ObjectId> > > LookupStartingWithTopics( SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { var pipeline = new EmptyPipelineDefinition <TTopic>() .As <TTopic, TTopic, TTopic>(); var pipeline2 = pipeline.Match(ToTopicSettingsFilter(parameters, subscribersRange)) .As <TTopic, TTopic, BsonDocument>(); pipeline2 = AddCategoryLookupStages(pipeline2, parameters, subscribersRange); pipeline2 = AddDeliveryTypeLookupStages(pipeline2, parameters, subscribersRange); //var bsonDocs = _collectionFactory.GetCollection<TTopic>().Aggregate(pipeline2).ToList(); //string jsonResults = bsonDocs.Select(x => x.ToJsonIntended()).Join(","); //return null; PipelineDefinition <TTopic, Subscriber <ObjectId> > pipelineProjected = AddSubscribersProjectionAndLimitStage(pipeline2, subscribersRange); return(_collectionFactory.GetCollection <TTopic>() .Aggregate(pipelineProjected) .ToListAsync()); }
protected virtual PipelineDefinition <TInput, BsonDocument> AddDeliveryTypeLookupStages <TInput>( PipelineDefinition <TInput, BsonDocument> pipeline, SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { string deliveryTypeCollection = _collectionFactory.GetCollection <TDeliveryType>().CollectionNamespace.CollectionName; string deliveryTypeField = FieldDefinitions.GetFieldMappedName <TTopic>(x => x.DeliveryType); string subscriberIdField = FieldDefinitions.GetFieldMappedName <TTopic>(x => x.SubscriberId); string topicLastSendDateField = FieldDefinitions.GetFieldMappedName <TTopic>(x => x.LastSendDateUtc); string lastVisitField = FieldDefinitions.GetFieldMappedName <TDeliveryType>(x => x.LastVisitUtc); string deliveryTypeIntermediateField = "dts"; string matchConditions = ToDeliveryTypeSettingsLookupFilter(parameters, subscribersRange); string deliveryTypeLookup = $@" {{ $lookup : {{ from: ""{deliveryTypeCollection}"", let: {{ delivery_type: ""${deliveryTypeField}"", subscriber_id: ""${subscriberIdField}"" }}, pipeline: [{{ $match: {{ {matchConditions} }} }}], as: ""{deliveryTypeIntermediateField}"" }} }}"; string hasDeliveryTypesAfterLookupStage = $@" {{ $match: {{ {deliveryTypeIntermediateField}: {{ $exists: true, $ne: [] }} }} }}"; string unwindStage = $"{{ $unwind: \"${deliveryTypeIntermediateField}\" }}"; string lastSendDateMatchStage = $@" {{ $match: {{ $or: [ {{ {topicLastSendDateField}: {{ $exists: false }} }}, {{ $and: [ {{ ""{deliveryTypeIntermediateField}.{lastVisitField}"": {{ $exists: true }} }}, {{ $expr: {{ $gt: [""{deliveryTypeIntermediateField}.{lastVisitField}"", ""{topicLastSendDateField}""] }} }} ] }} ] }} }}"; string replaceRootStage = $"{{ $replaceRoot: {{ newRoot: \"${deliveryTypeIntermediateField}\" }} }}"; pipeline = pipeline .AppendStage(deliveryTypeLookup, BsonDocumentSerializer.Instance) .AppendStage(hasDeliveryTypesAfterLookupStage, BsonDocumentSerializer.Instance) .AppendStage(unwindStage, BsonDocumentSerializer.Instance); if (subscribersRange.SelectFromTopics && parameters.CheckTopicLastSendDate) { pipeline = pipeline.AppendStage(lastSendDateMatchStage, BsonDocumentSerializer.Instance); } return(pipeline.AppendStage(replaceRootStage, BsonDocumentSerializer.Instance)); }
protected virtual IQueryable <SubscriberDeliveryTypeSettingsLong> JoinWithTopicsSelect(SubscriptionParameters parameters, SubscribersRangeParameters <long> subscribersRange , IQueryable <SubscriberDeliveryTypeSettingsLong> typeQueryPart, IQueryable <SubscriberTopicSettingsLong> topicQueryPart) { int categoryIdValue = parameters.CategoryId.Value; string topicIdValue = subscribersRange.TopicId ?? parameters.TopicId; IQueryable <SubscriberDeliveryTypeSettingsLong> query = null; if (parameters.CheckTopicLastSendDate) { query = from d in typeQueryPart join t in topicQueryPart on new { SubscriberId = d.SubscriberId, CategoryId = categoryIdValue, DeliveryType = d.DeliveryType, TopicId = topicIdValue } equals new { SubscriberId = t.SubscriberId, CategoryId = t.CategoryId, DeliveryType = t.DeliveryType, TopicId = t.TopicId } where (t.LastSendDateUtc == null || (d.LastVisitUtc != null && t.LastSendDateUtc < d.LastVisitUtc)) select d; } else { query = from d in typeQueryPart join t in topicQueryPart on new { SubscriberId = d.SubscriberId, CategoryId = categoryIdValue, DeliveryType = d.DeliveryType, TopicId = topicIdValue } equals new { SubscriberId = t.SubscriberId, CategoryId = t.CategoryId, DeliveryType = t.DeliveryType, TopicId = t.TopicId } select d; } return(query); }
//subscriber query filters public virtual FilterDefinition <TDeliveryType> ToDeliveryTypeSettingsFilter( SubscriptionParameters parameters, SubscribersRangeParameters <ObjectId> subscribersRange) { var filter = Builders <TDeliveryType> .Filter .Where(p => p.Address != null); if (subscribersRange.FromSubscriberIds != null) { filter &= Builders <TDeliveryType> .Filter.Where( p => subscribersRange.FromSubscriberIds.Contains(p.SubscriberId)); } if (subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { filter &= Builders <TDeliveryType> .Filter.Where( p => subscribersRange.SubscriberIdRangeFromIncludingSelf.Value <= p.SubscriberId); } if (subscribersRange.SubscriberIdRangeToIncludingSelf != null) { filter &= Builders <TDeliveryType> .Filter.Where( p => p.SubscriberId <= subscribersRange.SubscriberIdRangeToIncludingSelf.Value); } if (subscribersRange.SubscriberIdFromDeliveryTypesHandled != null && subscribersRange.SubscriberIdRangeFromIncludingSelf != null) { filter &= Builders <TDeliveryType> .Filter.Where( p => p.SubscriberId != subscribersRange.SubscriberIdRangeToIncludingSelf.Value || (p.SubscriberId == subscribersRange.SubscriberIdRangeToIncludingSelf.Value && !subscribersRange.SubscriberIdFromDeliveryTypesHandled.Contains(p.DeliveryType)) ); } if (parameters.DeliveryType != null) { filter &= Builders <TDeliveryType> .Filter.Where( p => p.DeliveryType == parameters.DeliveryType.Value); } if (parameters.CheckDeliveryTypeEnabled) { filter &= Builders <TDeliveryType> .Filter.Where( p => p.IsEnabled == true); } if (parameters.CheckDeliveryTypeLastSendDate) { filter &= Builders <TDeliveryType> .Filter.Where( p => p.LastSendDateUtc == null || (p.LastVisitUtc != null && p.LastVisitUtc > p.LastSendDateUtc)); } if (parameters.CheckDeliveryTypeSendCountNotGreater != null) { filter &= Builders <TDeliveryType> .Filter.Where( p => p.SendCount <= parameters.CheckDeliveryTypeSendCountNotGreater.Value); } if (parameters.CheckIsNDRBlocked) { filter &= Builders <TDeliveryType> .Filter.Where(p => p.IsNDRBlocked == false); } return(filter); }