Получите документы mongodb с определенными полями (проекциями) с помощью Spring-Integration (только аннотации) - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь получить все документы из коллекции mongodb, которые были изменены за последние 5 минут только с определенными полями (скажем, field1, field2, field3 и т. Д.).Как написать выражение LiteralExpression для получения определенных полей (проекций)?

Мои текущие выражения Literal возвращают документы, содержащие все поля (_id - метка времени создания документа в моей коллекции):

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;
    }
}

Какиевызывается в InboundChannelAdapter как

@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;
}

Есть ли способ, где я могу просто использовать MongoTemplate или MongoDbFactory вместо LiteralExpression для извлечения только определенных полей (проекция) в форме MongoDbMessageSource или любого другого формата, который может бытьподается в мой конвейер pubsubChannel.

1 Ответ

0 голосов
/ 25 февраля 2019

Это факт, что expression в качестве второго аргумента MongoDbMessageSource может быть разрешен для объекта org.springframework.data.mongodb.core.query.Query.Таким образом, это может быть не просто буквальное выражение .В вашем случае использования проекции вы можете написать что-то вроде:

new BasicQuery([QUERY_STRING], [FIELD_STRING])

, которое будет возвращено из вашего @myBean.getLiteralExpression().

Этот Query API довольно гибкий и обеспечивает свободное владение.хуки, которые нужно настроить для окончательного запроса MongoDB.Например, он имеет fields() для include/exclude обратных вызовов для определенных полей, которые вы хотели бы получить.

Подробнее о Query API в руководстве Spring Data MongoDB: https://docs.spring.io/spring-data/mongodb/docs/2.1.5.RELEASE/reference/html/#mongodb-template-query

Если вы хотите использовать MongoTemplate напрямую, вам нужно написать собственный код, который должен вызываться из оболочки MethodInvokingMessageSource с той же конфигурацией @InboundChannelAdapter.В этом коде вам все еще нужно создать такой Query объект, чтобы иметь возможность делегировать MongoTemplate.find().Это именно то, что делается в MongoDbMessageSource.

Вне всякого сомнения: ваша конфигурация DbReadingMessageSource() немного неверна.Вы не можете вызвать IntegrationFlows.from(messageSource); из этого определения бина.MongoDbMessageSource должен быть настроен как отдельный @Bean и уже без аннотации @InboundChannelAdapter.IntegrationFlow должен быть другим @Bean, и там вы действительно можете использовать свой DbReadingMessageSource() из этого from().Но опять же: без @InboundChannelAdapter.См. Справочное руководство: https://docs.spring.io/spring-integration/docs/current/reference/html/#java-dsl-inbound-adapters

...