笔者不用 mongodb 有几年时间了,最近有个项目使用的是 mongodb,但实际差不多是把它当做 mysql 在用,PS 不是我设计的。我临时帮忙,做一个统计功能。大概的需求是:根据设置列出可预约的日期以及每天的可预约量以及已经预约的量。
查询可预约日期以及每天的可预约量很简单,一条查询即可,但是,查询每天的已经预约的数量就比较困难了,实际等于是按天统计订单数量,mysql 可以使用 group by,mongodb 同样可以,但是,笔者在使用 mongodb 实现聚合查找时却遇到了一堆的坑,个个都是天坑。
笔者的代码大概是这样写的:
Criteria criteria = Criteria.where("orderInfo").
is(new DBRef("order_info", orderId))
.and("create_date").gte(beginDate).lte(endDate);
AggregationOperation match = Aggregation.match(criteria);
List aggregationOperationList = new ArrayList();
aggregationOperationList.add(match);
aggregationOperationList.add(Aggregation.project("create_date")
.and(DateOperators.dateOf("create_date")
.toString("%Y-%m-%d")).as("createDate"));
aggregationOperationList.add(Aggregation.group("createDate").first("create_date")
.as("createDate").count().as("totalCount"));
return mongoTemplate.aggregate(Aggregation.newAggregation(aggregationOperationList),
"UserOrder.class", OrderAnalytics.class).getMappedResults();
但是,这段代码却有两个坑,首先,mongodb 聚合查找不能使用class 名称,即,最后一行不能使用 UserOrder.class,你应该使用 user_order,但是 mongodb 其他的查询中,你完全可以使用 class 名称。。。这简直就是天坑,可能跟 mongodb 版本有关,具体原因实在没空去深究。
如果你使用 class 名称会抛出类似这样的异常:org.springframework.data.mapping.PropertyReferenceException: No property userOrder found for type UserOrder!
下次你在遇到类似的错误时,优先考虑下,是否是因为你使用了 类名,而导致无法找到响应的表名呢?
第二个坑,即最开始哪行:
Criteria criteria = Criteria.where("orderInfo").
is(new DBRef("order_info", orderId))
这里,你不应该直接使用 orderId,而应该使用 new ObjectId(orderId) 否则啥数据都查不到,但是在 query 中,你可以直接使用 orderId,而无需使用ObjectId 包裹。
这次的分享到此就结束了,关注我,带你一起踏平 bug。全栈之旅 - 分享编程经验与Linux技术,从不玩关注+私信那套。如果有用,记得收藏+分享哦。
领取专属 10元无门槛券
私享最新 技术干货