MongoDB查询或条件Spring数据

时间:2015-08-04 19:46:02

标签: mongodb spring-data mongodb-query spring-data-mongodb

我有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可以是pendinginprogress,但如果是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中创建它,我将不胜感激。

由于

1 个答案:

答案 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类型,但是您实例化日期。