MongoDB 日期范围查询在聚合中使用时抛出语法错误
MongoDB date range query throws syntax errors when used in aggregation
我正在使用 Java MongoDB 的驱动程序来查询数据库。尝试在聚合中的日期字段上执行 运行ge 查询时出现语法错误。如果我仅将它用作查找查询的一部分,它就可以正常工作。聚合是这里的问题。我使用了以下 Java 查询代码:
new BasicDBObject("requestDate", BasicDBObjectBuilder.start("$gte", fromDate).add("$lte", toDate).get());
requestDate是我要查询的字段。我尝试使用命令行调试代码和 运行 生成的查询,但我仍然遇到语法错误。不知道这里出了什么问题。
Mongo 代码生成的查询:
{ "requestDate" : { "$gte" : { "$date" : "2015-03-01T05:00:00.000Z"} , "$lte" : { "$date" : "2015-03-09T04:00:00.000Z"}}}
编辑。添加相关代码:
BasicDBObject match = null;
if (organizationId != null) {
match = new BasicDBObject("$match", new BasicDBObject("organizationId", organizationId));
}
if (optionalParams != null) {
Date fromDate = (Date) optionalParams.get("fromDate");
Date toDate = (Date) optionalParams.get("toDate");
if (match == null) {
match = new BasicDBObject("requestDate", new BasicDBObject("$gte", fromDate).append("$lte", toDate));
} else {
match.append("requestDate", new BasicDBObject("$gte", fromDate).append("$lte", toDate));
}
}
DBObject project = new BasicDBObject("$project", MongoDBUtil.getProjectDateFields());
DBObject groupFields = new BasicDBObject("_id", MongoDBUtil.getGroupDateFields()).append("total", new BasicDBObject("$sum", 1));
DBObject group = new BasicDBObject("$group", groupFields);
DBObject sort = new BasicDBObject("$sort", new BasicDBObject("_id", 1));
List<DBObject> pipeline;
if (match != null) {
pipeline = Arrays.asList(match, project, group, sort);
} else {
pipeline = Arrays.asList(project, group, sort);
}
简而言之,您破坏了 $match
流水线阶段构造,因为像所有流水线指令一样,"key" 是 "mandatory. Your conditional building should not be checking is the existing state is null
but rather " 附加到您需要在顶部定义为 "empty" $match
:
// BasicDBObject match = null; // wrong!
BasicDBObject match = new BasicDBObject("$match", new BasicDBObject()); // correct!
if (organizationId != null) {
match.append("organizationId", organizationId);
}
if (optionalParams != null) {
Date fromDate = (Date) optionalParams.get("fromDate");
Date toDate = (Date) optionalParams.get("toDate");
match.append("requestDate", new BasicDBObject("$gte", fromDate)
.append("$lte", toDate));
}
那么,如果没有 organizationId
的值,您会生成如下管道:
{ "$match": {
"requestDate" : {
"$gte" : { "$date" : "2015-03-01T05:00:00.000Z" },
"$lte" : { "$date" : "2015-03-09T04:00:00.000Z" }
}
}
没有那个 $match
键,这不是一个有效的管道阶段,它会在提交到聚合管道时出错。
生成的语法没有任何问题,所有完整的解释都在 Extended JSON 下的手册中。 MongoShell 使用那里提到的 "strict" 模式,因此它需要它自己的包装器。
我正在使用 Java MongoDB 的驱动程序来查询数据库。尝试在聚合中的日期字段上执行 运行ge 查询时出现语法错误。如果我仅将它用作查找查询的一部分,它就可以正常工作。聚合是这里的问题。我使用了以下 Java 查询代码:
new BasicDBObject("requestDate", BasicDBObjectBuilder.start("$gte", fromDate).add("$lte", toDate).get());
requestDate是我要查询的字段。我尝试使用命令行调试代码和 运行 生成的查询,但我仍然遇到语法错误。不知道这里出了什么问题。
Mongo 代码生成的查询:
{ "requestDate" : { "$gte" : { "$date" : "2015-03-01T05:00:00.000Z"} , "$lte" : { "$date" : "2015-03-09T04:00:00.000Z"}}}
编辑。添加相关代码:
BasicDBObject match = null;
if (organizationId != null) {
match = new BasicDBObject("$match", new BasicDBObject("organizationId", organizationId));
}
if (optionalParams != null) {
Date fromDate = (Date) optionalParams.get("fromDate");
Date toDate = (Date) optionalParams.get("toDate");
if (match == null) {
match = new BasicDBObject("requestDate", new BasicDBObject("$gte", fromDate).append("$lte", toDate));
} else {
match.append("requestDate", new BasicDBObject("$gte", fromDate).append("$lte", toDate));
}
}
DBObject project = new BasicDBObject("$project", MongoDBUtil.getProjectDateFields());
DBObject groupFields = new BasicDBObject("_id", MongoDBUtil.getGroupDateFields()).append("total", new BasicDBObject("$sum", 1));
DBObject group = new BasicDBObject("$group", groupFields);
DBObject sort = new BasicDBObject("$sort", new BasicDBObject("_id", 1));
List<DBObject> pipeline;
if (match != null) {
pipeline = Arrays.asList(match, project, group, sort);
} else {
pipeline = Arrays.asList(project, group, sort);
}
简而言之,您破坏了 $match
流水线阶段构造,因为像所有流水线指令一样,"key" 是 "mandatory. Your conditional building should not be checking is the existing state is null
but rather " 附加到您需要在顶部定义为 "empty" $match
:
// BasicDBObject match = null; // wrong!
BasicDBObject match = new BasicDBObject("$match", new BasicDBObject()); // correct!
if (organizationId != null) {
match.append("organizationId", organizationId);
}
if (optionalParams != null) {
Date fromDate = (Date) optionalParams.get("fromDate");
Date toDate = (Date) optionalParams.get("toDate");
match.append("requestDate", new BasicDBObject("$gte", fromDate)
.append("$lte", toDate));
}
那么,如果没有 organizationId
的值,您会生成如下管道:
{ "$match": {
"requestDate" : {
"$gte" : { "$date" : "2015-03-01T05:00:00.000Z" },
"$lte" : { "$date" : "2015-03-09T04:00:00.000Z" }
}
}
没有那个 $match
键,这不是一个有效的管道阶段,它会在提交到聚合管道时出错。
生成的语法没有任何问题,所有完整的解释都在 Extended JSON 下的手册中。 MongoShell 使用那里提到的 "strict" 模式,因此它需要它自己的包装器。