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 = Instant.now().minus(5, ChronoUnit.MINUTES).toEpochMilli();
long outerBoundary = Instant.now().toEpochMilli();
String expression = new StringBuilder()
.append("{'_id': {'$gt': ")
.append(innerBoundary)
.append(", '$lt' : ")
.append(outerBoundary)
.append("}}")
.toString();
return expression;
}
}
Which is being invoked in InboundChannelAdapter as
@Bean
@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)));
IntegrationFlows.from(messageSource);
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 org.springframework.data.mongodb.core.query.Query
object. So, it might not be just a plain literal expression . For your projection use-case you may write something like:
new BasicQuery([QUERY_STRING], [FIELD_STRING])
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: https://docs.spring.io/spring-data/mongodb/docs/2.1.5.RELEASE/reference/html/#mongodb-template-query
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: https://docs.spring.io/spring-integration/docs/current/reference/html/#java-dsl-inbound-adapters
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.