Morphia java .util.Arrays $ ArrayList нельзя преобразовать в com.mongodb.DBObject при создании Projection.projection - PullRequest
2 голосов
/ 05 мая 2020

Я пытаюсь поместить следующую агрегацию

db.getCollection("order").aggregate(
    [
        { 
            "$project" : {
                "_id" : -1.0, 
                "customerId" : "$customer.customerId", 
                "hasOrderInT0" : {
                    "$cond" : [
                        {
                            "$and" : [
                                {
                                    "$gte" : [
                                        "$date", 
                                        1577829600.0
                                    ]
                                }, 
                                {
                                    "$lte" : [
                                        "$date", 
                                        1580507999.0
                                    ]
                                }
                            ]
                        }, 
                        1, 
                        0
                    ]
                }
            }
        }
    ]
);

в приложение Java, где я использую Morphia как ORM. Обычно, если дата находится между двумя отметками времени, в поле hasOrderInT0 ставится 1, в противном случае - 0.

long initialStart = 1577829600;
long initialEnd = 1580507999;

AggregationPipeline pipeline = databaseService.getConnection().createAggregation(Order.class)
                .project(
                        Projection.projection("_id", "-1"),
                        Projection.projection("customerId", "$customer.customerId"),
                        Projection.projection("hasOrderInT0",
                                Projection.expression(
                                        "$cond",
                                        Arrays.<Object>asList(
                                                new BasicDBObject(
                                                        "$and", Arrays.<Object>asList(
                                                        new BasicDBObject(
                                                                "$gte", Arrays.<Object>asList("$date", initialStart)
                                                        ),
                                                        new BasicDBObject(
                                                                "$lte", Arrays.<Object>asList("$date", initialEnd)
                                                        )
                                                )
                                                ),
                                                1,
                                                0
                                        )
                                )
                        )
                );

При запуске приведенного выше кода я получаю следующую ошибку:

Caused by: java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to com.mongodb.DBObject
    at xyz.morphia.aggregation.AggregationPipelineImpl.toExpressionArgs(AggregationPipelineImpl.java:296)
    at xyz.morphia.aggregation.AggregationPipelineImpl.toDBObject(AggregationPipelineImpl.java:249)
    at xyz.morphia.aggregation.AggregationPipelineImpl.toDBObject(AggregationPipelineImpl.java:240)
    at xyz.morphia.aggregation.AggregationPipelineImpl.project(AggregationPipelineImpl.java:191)

Я впервые использую проекцию с Morphia, и я не знаю, правильно ли это способ реализовать команду, которая работает в консоли mon go.

PS: $project - это просто конвейер из более крупного агрегата, но это та часть, которая представляет интерес и которая выдает ошибку , поэтому я упростил его для демонстрации.

1 Ответ

1 голос
/ 07 мая 2020

Оказывается, нет необходимости переносить условие из $ cond в Arrays.<Object>asList. Projection.expression уже принимает произвольное количество аргументов, поэтому рабочий код:

long initialStart = 1577829600;
long initialEnd = 1580507999;

AggregationPipeline pipeline = databaseService.getConnection().createAggregation(Order.class)
                .project(
                        Projection.projection("_id", "-1"),
                        Projection.projection("customerId", "$customer.customerId"),
                        Projection.projection("hasOrderInT0",
                                Projection.expression(
                                        "$cond",
                                            new BasicDBObject(
                                                    "$and", Arrays.<Object>asList(
                                                    new BasicDBObject(
                                                            "$gte", Arrays.<Object>asList("$date", initialStart)
                                                    ),
                                                    new BasicDBObject(
                                                            "$lte", Arrays.<Object>asList("$date", initialEnd)
                                                    )
                                            )
                                            ),
                                            1,
                                            0
                                )
                        )
                );

BasicDBObject - это первый аргумент, 1 и 0 - это второй и третий, и они будут правильно интерпретированы оболочкой Morphia. .

...