MongoDB日期范围查询在聚合中使用时会引发语法错误

时间:2015-03-09 21:42:49

标签: java mongodb mongodb-query aggregation-framework

我正在使用Java Driver for MongoDB来查询数据库。尝试在聚合中的日期字段上执行范围查询时,我收到语法错误。如果我只将它用作查询查询的一部分,它可以正常工作。聚合是这里的问题。我使用了以下Java查询代码:

new BasicDBObject("requestDate", BasicDBObjectBuilder.start("$gte", fromDate).add("$lte", toDate).get());

requestDate是我要查询的字段。我尝试调试代码并使用命令行运行生成的查询,但仍然会出现语法错误。不知道这里有什么不对。

代码生成的Mongo Query:

 { "requestDate" : { "$gte" : { "$date" : "2015-03-01T05:00:00.000Z"} , "$lte" : { "$date" : "2015-03-09T04:00:00.000Z"}}}

EDIT。添加相关代码:

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);
}

1 个答案:

答案 0 :(得分:1)

简而言之,您打破了$match管道阶段的构建,因为像所有管道指令一样,&#34; key&#34;是强制性的。您的条件建筑不应该检查现有状态是null而是&#34;追加&#34;你需要在顶部定义为&#34;空&#34; $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使用&#34; strict&#34;如上所述的模式,所以它需要它自己的包装。