3

I needed to find all the records in mongo db within two date ranges using Mongo Driver[3.4.0] for Java.

Example: I have books Collection.

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

Like above I have 100s of documents.

I need to find all records wherein pub-date > rel-date.

I am using Mongo DB version 3.2.6

I tried to use $expr operator but it seems to work with only Mongo 3.6+

Not able find cleaner solutions for above requirement.

Please clarify.

2 Answers 2

3

The MongoDB (prior to v3.4) shell command for your use case is:

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

Translating this command into Java you'll get:

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

Given a collection with these documents ...

{
    "_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")
}

.. the above Java code will print ...

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

... because this document's pub-date (2013-11-02T00:00:00.000Z) is after its rel-date (2013-10-02T00:00:00.000Z).

Note: the $where operator is functionally equivalent but use of that operator comes with some limitations:

$where evaluates JavaScript and cannot take advantage of indexes. Therefore, query performance improves when you express your query using the standard MongoDB operators (e.g., $gt, $in).

In general, you should use $where only when you can’t express your query using another operator. If you must use $where, try to include at least one other standard query operator to filter the result set. Using $where alone requires a collection scan.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the detailed answer.
1

You might want to try $where-Operator:

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

2 Comments

Thanks. But how do I use the above query with Java BasicDBObject class ?
You might want to consider the limitations of $where especially since the aggregation framework can be used (via the MongoDB Java driver) to produce the result you require.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.