Morphia java.util.Arrays$ArrayList cannot be cast to com.mongodb.DBObject when making a Projection.projection

huangapple go评论70阅读模式
英文:

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.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 包装器正确解释。

英文:

It turns out there is no need to wrap the condition from $cond into in Arrays.&lt;Object&gt;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(&quot;_id&quot;, &quot;-1&quot;),
                        Projection.projection(&quot;customerId&quot;, &quot;$customer.customerId&quot;),
                        Projection.projection(&quot;hasOrderInT0&quot;,
                                Projection.expression(
                                        &quot;$cond&quot;,
                                            new BasicDBObject(
                                                    &quot;$and&quot;, Arrays.&lt;Object&gt;asList(
                                                    new BasicDBObject(
                                                            &quot;$gte&quot;, Arrays.&lt;Object&gt;asList(&quot;$date&quot;, initialStart)
                                                    ),
                                                    new BasicDBObject(
                                                            &quot;$lte&quot;, Arrays.&lt;Object&gt;asList(&quot;$date&quot;, 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.

huangapple
  • 本文由 发表于 2020年5月5日 19:58:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/61612605.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定

  • 开发者交流平台

    本页二维码