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} ]"); }
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)); }
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} ]"); }
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)); }