这是我的Mongo Pojo也是getter和setters(未添加)。
@CompoundIndex(name = "account_date_idx", def = "{'account' : 1, 'date' : 1}", unique = true)
@Document(collection = "agent_data_storage")
public class AgentDataStorage extends MongoKeyedEntity<String> implements Serializable {
public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Field
private Long account;
@Field()
private String date;
@Field
private Map<String, Double> dataPoints = new HashMap<>();
public AgentDataStorage() {
}
public AgentDataStorage(Long account) {
this.account = account;
this.date = dateFormat.format(new Date());
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(String account) {
this.account = Long.valueOf(account);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(Long account, Date date) {
this.account = account;
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(Long account, Date date, Map<String, Double> dataPoints) {
this.account = account;
this.date = dateFormat.format(date);
this.dataPoints = dataPoints;
}
public AgentDataStorage(Long account, String date, Map<String, Double> dataPoints) {
this.account = account;
this.date = date;
this.dataPoints = dataPoints;
}
public AgentDataStorage(String account, Date date) {
this.account = Long.valueOf(account);
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(String account, String date) {
this.account = Long.valueOf(account);
this.date = date;
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public Long getAccount() {
return account;
}
public void setAccount(Long account) {
this.account = account;
}
public Date getDate() throws ParseException {
return dateFormat.parse(this.date);
}
public void setDate(Date date) {
this.date = dateFormat.format(date);
}
public Map<String, Double> getDataPoints() {
return dataPoints;
}
public void setDataPoints(Map<String, Double> dataPoints) {
this.dataPoints = dataPoints;
}
public void updateDataPoint(AgentDataPoints agentDataPoints, Double value) {
this.dataPoints.put(String.valueOf(agentDataPoints), value);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AgentDataStorage{");
sb.append("account=").append(account);
sb.append(", date=").append(date);
sb.append(", dataPoints=").append(dataPoints);
sb.append('}');
return sb.toString();
}
}
尝试聚合时,我得到空指针异常,下面是我的测试用例。
@Test
public void aggregationTest() {
Long account = 12121l;
String startDay = "2016-01-01";
String endDay = "2016-01-03";
Aggregation aggregation = Aggregation
.newAggregation(match(Criteria.where("account").is(account).and("date")
.gte(startDay).lte(endDay)),
group("account").sum("dataPoints.TOTAL_BUS_COMMISSION").as("total"));
AggregationResults<AggregationResult> results = mongoTemplate.aggregate(aggregation,
AgentDataStorage.class, AggregationResult.class);
}
我的AggregationResult类是 -
public class AggregationResult {
private Long _id;
private Double total;
public Long get_id() {
return _id;
}
public void set_id(Long _id) {
this._id = _id;
}
public Double getTotal() {
return total;
}
public void setTotal(Double total) {
this.total = total;
}
}
下面是Stack Trace of Error
java.lang.NullPointerException
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:233)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:214)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:210)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReferenceFor(TypeBasedAggregationOperationContext.java:96)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReference(TypeBasedAggregationOperationContext.java:91)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.getValue(GroupOperation.java:434)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.toDBObject(GroupOperation.java:416)
at org.springframework.data.mongodb.core.aggregation.GroupOperation.toDBObject(GroupOperation.java:361)
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:331)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1500)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1435)
at psl.service.core.agentanalytics.internal.AgentAnalyticsServiceTest.aggregationTest(AgentAnalyticsServiceTest.java:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:81)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
我也尝试调试内部的spring jar,它在AbstractMappingContext.java中为Double类型抛出null,但是不能理解它为什么会发生。 mongo控制台正在使用相同的mongo查询。
db.getCollection('agent_data_storage').aggregate([
{ "$match" : { "account" : 12121 , "date" : { "$gte" : "2016-01-01" , "$lte" : "2016-01-03"}}}
, { "$group" : { "_id" : "$account" , "total" : { "$sum" : "$dataPoints.TOTAL_BUS_COMMISSION"}}}])
上述查询的结果是
{
"_id" : NumberLong(12121),
"total" : 402.0
}
感谢您提供任何帮助。
来自AgentDataStorage的示例文档 -
{
"_id" : ObjectId("586233e3fb94f6f5640196cf"),
"account" : NumberLong(12121),
"date" : "2016-01-01",
"dataPoints" : {
"TOTAL_BUS_COMMISSION" : 0.0
}
}
答案 0 :(得分:2)
不要使用聚合的类型聚合变体,它主要是尝试将输入类型(AgentDataStorage)中的属性引用转换为字段名称,并且在它没有找到属性引用时失败,在您的情况下dataPoints.TOTAL_BUS_COMMISSION。
使用
AggregationResults<AggregationResult> results = mongoTemplate.aggregate(aggregation,
"agent_data_storage", AggregationResult.class);