QueryDSL NumberPath <BigDecimal>Больше, чем выдача неточных результатов из MongoDB Collection - PullRequest
0 голосов
/ 12 мая 2018

При попытке применить реализацию QueryDSL для фильтрации поиска я столкнулся со следующей проблемой, которая, по меньшей мере, весьма запутана.

Рассмотрим следующие свойства в коллекции MongoDB под названием Payments:

Объект 1 - amountDue (Object) - amount => 106.00 (String)

Объект 2 - amountDue (Object) - amount => 58.80 (String)

Эти значения генерируются системой, и фактическим типом данных объекта amountDue является org.joda.Объект BigMoney.

Эти свойства применяются в методе привязки, который используется для предоставления предиката QueryDSL, так что возвращаются любые объекты Payment, у которых свойство amountDue.amount больше, чем указано в поисковом запросе.Такой метод описан ниже:

@Override
public Predicate bind(NumberPath<BigDecimal> bigDecimalNumberPath, Collection<? extends BigDecimal> value) {
        ArrayList<? extends BigDecimal> amounts = new ArrayList<>(value);

        return bigDecimalNumberPath.gt(amounts.get(0));
    }

Ниже описываются случаи, с которыми я тестирую, среди прочего, с соответствующими результатами:

{URL}/payments/filter?page=0&amountDue.amount=10.00, который внутренне преобразуется в 'amountDue.amount> 10.00' предикат возвращает оба объекта [Correct]

{URL}/payments/filter?page=0&amountDue.amount=20.00, которые внутренне преобразуются в 'amountDue.amount> 20.00' возвращает только Объект 2 [Неверно]

{URL}/payments/filter?page=0&amountDue.amount=60.00, который внутренне преобразуется в предикат 'amountDue.amount> 60.00' , не возвращает объектов [Неверно]

{URL}/payments/filter?page=0&amountDue.amount=100.00, который внутренне преобразуется в предикат 'amountDue.amount> 100.00' , возвращает только объект 2 [Неверно]

{URL}/payments/filter?page=0&amountDue.amount=150.00, который внутренне преобразуется в 'amountDue.amount> 150.00 ' предикат возвращает только Объект 2 [Неверно]

В тот момент, когда значение amount для Объекта 1 изменяется на значение меньше 100, все случаи возвращают правильные результаты.

Что вы предлагаетеИоны / рекомендации, пожалуйста?

Спасибо за ваше время !!

1 Ответ

0 голосов
/ 12 мая 2018

Для решения проблемы, указанной выше, было применено следующее:

Сначала создайте преобразователь класса Decimal128 (тип Bson) в большое десятичное число:

public class Decimal128ToBigDecimalConverter implements Converter<Decimal128, BigDecimal> {

    @Override
    public BigDecimal convert(Decimal128 source) {
        return source.bigDecimalValue();
    }
}

Затем создайте большое десятичное число дляПреобразователь класса Decimal128 (Bson Type):

public class BigDecimalToDecimal128Converter implements Converter<BigDecimal, Decimal128> {

    @Override
    public Decimal128 convert(BigDecimal source) {
        return new Decimal128(source);
    }
}

Наконец, настройте файл MongoConfig для использования преобразователей:

@Bean
public MongoTemplate mongoTemplate() throws Exception {

    MongoTemplate mongoTemplate = new MongoTemplate(mongo(), getDatabaseName());
    MappingMongoConverter mongoMapping = (MappingMongoConverter) mongoTemplate.getConverter();
    mongoMapping.setCustomConversions(customConversions()); 
    mongoMapping.afterPropertiesSet();
    return mongoTemplate;

}

public CustomConversions customConversions() {
    return new CustomConversions(Arrays.asList(new Decimal128ToBigDecimalConverter(), new BigDecimalToDecimal128Converter()));
}


/* (non-Javadoc)
 * @see org.springframework.data.mongodb.config.AbstractMongoConfiguration#mongo()
 */
@Bean
@Override
public Mongo mongo() throws Exception
{
    return new MongoClient();
}

Решение было реализовано, следуя приведенному ниже примеру: http://ufasoli.blogspot.com.mt/2017/06/custom-converter-for-mongodb-and-spring.html

...