英文:
Morphia java.util.Arrays$ArrayList cannot be cast to com.mongodb.DBObject when making a Projection.projection
问题
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.asList(
                    new BasicDBObject(
                        "$and", Arrays.asList(
                            new BasicDBObject("$gte", Arrays.asList("$date", initialStart)),
                            new BasicDBObject("$lte", Arrays.asList("$date", initialEnd))
                        )
                    ),
                    1,
                    0
                )
            )
        )
    );
英文:
I am trying to put the following aggregation
db.getCollection("order").aggregate(
    [
        { 
            "$project" : {
                "_id" : -1.0, 
                "customerId" : "$customer.customerId", 
                "hasOrderInT0" : {
                    "$cond" : [
                        {
                            "$and" : [
                                {
                                    "$gte" : [
                                        "$date", 
                                        1577829600.0
                                    ]
                                }, 
                                {
                                    "$lte" : [
                                        "$date", 
                                        1580507999.0
                                    ]
                                }
                            ]
                        }, 
                        1, 
                        0
                    ]
                }
            }
        }
    ]
);
in a Java app, where I am using Morphia as ORM. Basically if the date is between 2 timestamps, it will put 1 in the hasOrderInT0 field and 0 otherwise.
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
                                        )
                                )
                        )
                );
When running the above code, I get the following error:
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)
This is my first time using Projection with Morphia and I don't know if this is the right way to implement the command that works in mongo console.
PS: The $project is just a pipeline from a bigger aggregate, but this is the part that is of interest and which is giving the error, so I simplified it for demonstration purpose.
答案1
得分: 1
这实际上不需要将 $cond 中的条件从 $cond 包装到 "Arrays.
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 包装器正确解释。
英文:
It turns out there is no need to wrap the condition from $cond into in Arrays.<Object>asList. Projection.expression already accepts an arbitrary number of arguments, so the working code is:
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
                                )
                        )
                );
The BasicDBObject is the first arg, 1 and 0 are the 2nd and 3rd and they will be correctly interpreted by Morphia wrapper.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论