我有status
个集合,其中有四个字段abc, xyz, status, time
我想为下面的MySql查询创建MongoDB查询:
select * from status where abc = false and xyz = true and (status = pending or (status = inprogress and time = "2015-08-04"))
基本上status
可以是pending
或inprogress
,但如果是inprogress
则必须比较time
。
我尝试在MongodDB下面创建查询,但它无法正常工作
db.status.find
{
"abc" : false ,
"xyz" : true ,
"status" : "pending" ,
"$and" : [
{ "status" : "inprogress"} ,
{ "time" : { "$eq" : { "$date" : "2015-08-04"}}}
]
}
我正在使用Spring MongoDB,如果有人可以指导我如何在Spring Data MongoDb中创建它,我将不胜感激。
由于
答案 0 :(得分:1)
您正在尝试的当前查询存在一些问题。首先要理解的是,所有操作都是隐含的,并且" AND"条件,除非另有说明。因此,您在此处缺少的$or
条件必须包含"两者"状态测试和其他组合"时间"这样的条件:
db.status.find({
"abc" : false,
"xyz" : true,
"$or" : [
{ "status" : "pending" },
{
"status" : "inprogress"
"time" : "2015-08-04"
}
]
})
这里的SQL表示也意味着"时间"实际上是一个字符串。如果它以相同的方式存储在MongoDB文档中,那么上面就可以了。如果没有,并且值已在BSON中转换为实际Date
个对象,则必须提供BSON日期(或转换的内容)作为参数。通常日期不是"确切的",所以你使用"范围"代替:
db.status.find({
"abc" : false,
"xyz" : true,
"$or" : [
{ "status" : "pending" },
{
"status" : "inprogress"
"time" : { "$gte": new Date("2015-08-04"), "$lt": new Date("2015-08-05") }
}
]
})
对于弹簧翻译,将是:
Query query = new Query(Criteria.where("abc").is(false)
.and("xyz").is(true)
.orOperator(
Criteria.where("status").is("pending"),
Criteria.where("status").is("inprogress")
.and("time").is("2015-08-04")
)
);
或者使用真实日期对象和范围:
DateTime startDay = new DateTime(2015, 8, 4, 0, 0, DateTimeZone.UTC);
Date startDate = startDay.toDate();
Date endDate = startDay.plusDays(1).toDate();
Query query = new Query(Criteria.where("abc").is(false)
.and("xyz").is(true)
.orOperator(
Criteria.where("status").is("pending"),
Criteria.where("status").is("inprogress")
.and("time").gte(startDate).lt(endDate)
)
);
至少从记忆中应该是正确的,就像现在远离IDE一样。还要注意"链接"这里的运营商如$gte
和$lt
也意味着" AND"条件分配给同一个键的值。
在处理日期时,基础驱动程序期望所有与BSON日期匹配的输入都被转换为java.util.Date类型,但是您实例化日期。