“范围选择”指定不正确,您的使用$and
不正确。实际上,只考虑了“最后一个”参数,因此它只是在寻找“大于myId
等于10
”的日期的所有内容,这当然是不正确的。
这是您的正确查询语法$match
:
{ "$match": {
"myDate": {
"$gte": new Date(949384052490),
"$lte": new Date(1448257684431)
},
"myId": 10,
"type": { "$ne": "Contractor" }
}}
不需要任何$and
,因为所有 MongoDB 查询参数都已经是AND条件。
您还应该考虑组合$project
和$group
阶段,因为这通常意味着当它们一个接一个地发生时可以组合它们。至少这样更有效率。
但当然,大部分时间都浪费在了最初的$match
中,无论如何都会选择不正确的结果。
$group
和 no的最佳管道$project
:
{ "$group": {
"_id": {
"retailerName": "$retailerName",
"year": { "$year": "$myDate" },
"currency": "$currency"
},
"netSales": { "$sum": "$revenue" },
"netUnitSold": { "$sum": "$unitSold" },
"totalSales": { "$sum":
{ "$multiply": [ "$unitSold", "$itemPrice" ] }
}
}}
所以整个管道现在就在$match
那时$group
。
使用 spring mongo
如果您使用的是 spring-mongo,那么当前$group
受支持的运算符与复合键和累加器中的计算值的组合存在限制,但您可以解决这些问题。至于$and
语句,这实际上是语法问题,而不是 spring mongo 的错。
首先为聚合管道中的“组”设置一个自定义类:
public class CustomGroupOperation implements AggregationOperation {
private DBObject operation;
public CustomGroupOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
然后使用该类构建管道:
Aggregation aggregation = newAggregation(
match(
Criteria.where("myDate")
.gte(new Date(new Long("949384052490")))
.lte(new Date(new Long("1448257684431")))
.and("myId").is(10)
.and("type").ne("Contractor")
),
new CustomGroupOperation(
new BasicDBObject(
"$group", new BasicDBObject(
"_id", new BasicDBObject(
"retailerName", "$retailerName"
).append(
"year", new BasicDBObject("$year", "$myDate")
).append(
"currency", "$currency"
)
).append(
"netSales", new BasicDBObject("$sum","$revenue")
).append(
"netUnitSold", new BasicDBObject("$sum","$unitSold")
).append(
"totalSales", new BasicDBObject(
"$multiply", Arrays.asList("$unitSold", "$itemPrice")
)
)
)
)
);
这会产生一个这样的序列化管道:
[
{ "$match" : {
"myDate" : {
"$gte" : { "$date" : "2000-02-01T05:47:32.490Z"},
"$lte" : { "$date" : "2015-11-23T05:48:04.431Z"}
},
"myId" : 10,
"type" : { "$ne" : "Contractor"}
}},
{ "$group": {
"_id" : {
"retailerName" : "$retailerName",
"year" : { "$year" : "$myDate"},
"currency" : "$currency"
},
"netSales" : { "$sum" : "$revenue"},
"netUnitSold" : { "$sum" : "$unitSold"},
"totalSales" : { "$multiply" : [ "$unitSold" , "$itemPrice"]}
}}
]
这与上面给出的示例完全相同