Get mongodb documents with certain fields(projections) using Spring-Integration (annotations only)

I am trying to get all documents from a mongodb collection which were modfied in last 5 minutes with certain fields only (say field1, field2, field3 and so on). How to write a LiteralExpression to get specific fields (projections)?

My current Literal Expression return documents containing all fields (_id is timestamp of document creation in my collection):

public String getLiteralExpression(){
        long innerBoundary =, ChronoUnit.MINUTES).toEpochMilli();
        long outerBoundary =;
        String expression = new StringBuilder()
                .append("{'_id': {'$gt': ")
                .append(", '$lt' : ")
        return expression;

Which is being invoked in InboundChannelAdapter as

@InboundChannelAdapter(value = "pubSubChannel", poller = @Poller(fixedRate = "30000"))
public MessageSource<Object> DbReadingMessageSource() {

    Expression expression = new SpelExpressionParser().parseExpression("@myBean.getLiteralExpression()");

    MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoTemplate, expression);
    messageSource.setCollectionNameExpression(new LiteralExpression(mongoTemplate.getCollectionName(MyEntity.class)));
    return messageSource;

Is there a way where I can just use MongoTemplate or MongoDbFactory instead of a LiteralExpression to fetch only certain fields (projection) in form of MongoDbMessageSource or any other format which can be fed to my pubsubChannel pipeline.


It’s a fact that the expression as a second MongoDbMessageSource argument can be resolved to the object. So, it might not be just a plain literal expression. For your projection use-case you may write something like:


to be returned from your @myBean.getLiteralExpression().

That Query API is pretty flexible and provides a lot of fluent hooks to be configured for the final MongoDB query. For example it has a fields() for include/exclude callbacks for specific fields you would like to be returned.

More info about Query API in the Spring Data MongoDB manual:

If you would like to use MongoTemplate directly instead, you need to write a custom code which should be called from the MethodInvokingMessageSource wrapper with the same @InboundChannelAdapter configuration. In that code you still need to build such a Query object to be able to delegate to the MongoTemplate.find(). That is exactly what is done in the MongoDbMessageSource.

Out of question: your DbReadingMessageSource() configuration is slightly wrong. You can’t call IntegrationFlows.from(messageSource); from that bean definition. The MongoDbMessageSource must be configured as a separate @Bean and already without @InboundChannelAdapter annotation. The IntegrationFlow has to be another @Bean and there you really can use your DbReadingMessageSource() from that from(). But again: without @InboundChannelAdapter. See Reference Manual:

Leave a Reply

Your email address will not be published. Required fields are marked *