Mongodb Java查询日期范围

时间:2018-04-09 11:52:44

标签: java mongodb mongodb-query mongodb-java

我需要使用Mongo Driver [3.4.0] for Java在两个日期范围内找到mongo db中的所有记录。

实施例: 我有书籍收藏。

{
    "_id" : ObjectId("5acb40d27d63b61cb002bafe"),
    "title" : "WingsOfFire",
    "pub-date" : ISODate("2013-10-02T00:00:00.000Z"),
    "rel-date" : ISODate("2013-11-02T00:00:00.000Z")
}

如上所述,我有100多份文件。

我需要找到所有记录,其中pub-date> REL-日期。

我正在使用Mongo DB版本3.2.6

我尝试使用 $ expr 运算符,但它似乎只适用于Mongo 3.6 +

无法找到符合上述要求的清洁解决方案。

请澄清。

2 个答案:

答案 0 :(得分:2)

用于用例的MongoDB(v3.4之前的)shell命令是:

db.collection.aggregate([
    {
        "$redact": {
            "$cond": [
                { "$gt": [ "$pub-date", "$rel-date" ] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])

将此命令翻译成Java,您将获得:

MongoClient mongoClient = ...;

MongoCollection<Document> collection = mongoClient.getDatabase("...").getCollection("...");

List<Document> documents = collection.aggregate(Arrays.asList(
        new Document("$redact", new Document("$cond",
                Arrays.asList(new Document("$gt", Arrays.asList("$pub-date", "$rel-date")), "$$KEEP", "$$PRUNE"))
        ))).into(new ArrayList<>());

for (Document document : documents) {
    System.out.println(document.toJson());
}

鉴于这些文件的集合......

{
    "_id" : ObjectId("5acb40d27d63b61cb002bafe"),
    "title" : "WingsOfFire",
    "pub-date" : ISODate("2013-10-02T00:00:00.000Z"),
    "rel-date" : ISODate("2013-11-02T00:00:00.000Z")
}

{
    "_id" : ObjectId("5acb662756539a6734e64e4a"),
    "title" : "WingsOfSmoke",
    "pub-date" : ISODate("2013-11-02T00:00:00.000Z"),
    "rel-date" : ISODate("2013-10-02T00:00:00.000Z")
}

..以上Java代码将打印...

{ "_id" : { "$oid" : "5acb662756539a6734e64e4a" }, "title" : "WingsOfSmoke", "pub-date" : { "$date" : 1383350400000 }, "rel-date" : { "$date" : 1380672000000 } }

...因为此文件的pub-date(2013-11-02T00:00:00.000Z)位于rel-date之后(2013-10-02T00:00:00.000Z)

注意:$where运算符在功能上是等效的,但使用该运算符会带有一些limitations

  

$where评估JavaScript并且无法利用索引。因此,当您使用标准MongoDB运算符表达查询时,查询性能会提高(例如$gt$in)。

     

通常,只有当您无法使用其他运营商表达您的查询时,才应使用$where。如果必须使用$where,请尝试包含至少一个其他标准查询运算符以过滤结果集。单独使用$where需要进行集合扫描。

答案 1 :(得分:1)

您可能想尝试$where - 运营商:

db.books.find({ "$where": "this.pub-date > this.rel-date"});