Skip to content

watch changes to specific fields in MongoDB change stream with Spring Data Mongodb [DATAMONGO-2587] #3439

@spring-projects-issues

Description

@spring-projects-issues

Tita opened DATAMONGO-2587 and commented

Hello,

Im working  on an application that implement stream change for mongodb (Version 4.2.8)   , uning springboot mongodb reactive  and reactor kafka  to send all updated events to Kafka. i used an aggregation pipeline  to catch some updates fields on  my collection cdatabase, but unfortunately it does not work  ... here an example of my  filter aggregation .

  

 public static TypedAggregation<ProductStoreStock> getAggregatForUpdatedSpecificFields1() {
		
    	Criteria StkAvailableForSaleCriteria = where("updateDescription.updatedFields.stockAvailableForSale.lastUpdateDate").exists(true)  
                                             .and("updateDescription.updatedFields.stockAvailableForSale.value").exists(true);

	Criteria updateOperationTypeCrit = where(AggregationPipelineConstant.OPERATION_TYPE).is(OperationType.UPDATE.getValue());			
        Criteria criteria = new Criteria().andOperator(StkAvailableForSaleCriteria, updateOperationTypeCrit);
	return Aggregation.newAggregation(ProductStoreStock.class, match(criteria));
	}
 

and my filter is called by this watcher :

public ChangeStreamWithFilterAndProjection<ProductStoreStock> getWatcher() {
	    
		return mongoConfig.getReactiveMongoTemplate().changeStream(ProductStoreStock.class)
                    .watchCollection(CollectionName.PRODUCT_STORE_STOCK.getCollectionName())
                    .filter(AggregationUtils.getAggregatForUpdatedSpecificFields1()); 
	}

I get not change events. So here is the question: how can I define the Criteria to match updates on  updatedField.x.y.z ??

So, I tried to remove my stock filter while keeping only the operation type as 'update' and log of one of these change events looks like:

 

   "updateDescription=UpdateDescription"{
      "removedFields="[

      ],
      "updatedFields="{
         "lastUpdateDate":{
            "$date":"2020-07-13T14:17:04.655Z"
         },
         "stockAvailableForSale.lastUpdateDate":{
            "$date":"2020-07-13T14:17:04.655Z"
         },
         "stockAvailableForSale.value":-5.05,
         "stockAvailableImmediate.lastUpdateDate":{
            "$date":"2020-07-13T14:17:04.655Z"
         },
         "stockAvailableImmediate.value":-5.05
      }
   },

 
I changed my filter using matchElemnt, so that it looks like this  :
 

 public static TypedAggregation<ProductStoreStock> getAggregatForUpdatedSpecificFields1() {
	
		Criteria StkAvailableForSaleCriteria = where("updateDescription")
                         .elemMatch(where("updatedFields").exists(true))
                          .elemMatch(where("stockAvailableForSale.lastUpdateDate").exists(true));
    	
	Criteria updateOperationTypeCrit = where(AggregationPipelineConstant.OPERATION_TYPE).is(OperationType.UPDATE.getValue());			
        Criteria criteria = new Criteria().andOperator(StkAvailableForSaleCriteria, updateOperationTypeCrit);
	return Aggregation.newAggregation(ProductStoreStock.class, match(criteria));
	}
 

Result ->  No update event is catched !! 
Anyone can help me ?

Thanks in advance.

 


Attachments:

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions