与范围中的null日期进行比较

时间:2016-04-23 18:52:52

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

@Document
public class Product extends Item {
    private Date onlineDate;

    private Date offlineDate;
}

数据

Product {
    onlineDate : some date
    offlineDate : null
}

以下查询返回0次点击

query.addCriteria(Criteria.where("onlineDate").lte(date).and("offlineDate").gte(date))

但在查询下方返回结果

query.addCriteria(Criteria.where("onlineDate").lte(date))

这是我不允许与空日期比较的东西。

1 个答案:

答案 0 :(得分:1)

您基本上需要包含条件才能接受结果中的null。现在你要求“大于”提供的日期,null不是“大于”,因此它被排除在外。

这意味着添加$or条件以测试该字段上的两种可能条件:

Criteria criteria = Criteria.where("onlinedate").lte(date).orOperator(
    Criteria.where("offlinedate").gte(date),
    Criteria.where("offlinedate").is(null)
);

Query query = new Query().addCriteria(criteria);

System.out.println(query.getQueryObject());

哪会给你:

{ 
    "onlinedate" : { "$lte" : date } , 
    "$or" : [ 
        { "offlinedate" : { "$gte" : date } } , 
        { "offlinedate" :  null }
    ]
}

这是更改查询以允许null值的正确翻译,但它确实让我认为您对查询的基本思考是不正确的,因为这会返回基本上说“仍然存在的结果网上“的。这可能是你想要的,但是你可能一直想要问一些不同的东西。

如果实际上您正在查找的“全部”文档在文档中的两个值之间提供了date值,那么您将改为“反转”范围表达式匹配文档“之间”然后“反转”结果$nor代替:

Criteria criteria = new Criteria().norOperator(
   Criteria.where("onlinedate").gte(date)
   .and("offlinedate").lte(date)
);

Query query = new Query().addCriteria(criteria);

System.out.println(query.getQueryObject());

这会产生如下查询:

{
    "$nor" : [ 
        { 
            "onlinedate" : { "$gte" : date }, 
            "offlinedate" : { "$lte" : date }
        }
    ]
}

在两个日期属性之间的“之前”和“之后”返回结果,或者"offline"日期为null并且范围未“关闭”。

这取决于您实际需要的结果集,要么包含null值以查找“仍处于打开状态”的数据,要么只是“排除范围”以查找落下的数据而是在范围之外。