0

I am writing a process that will run every 1 hour and connect to a mongodb collection. The document in CollectionA has a timestamp key associated. The process then has to search all the new documents inserted in another collection Collection B after the timestamp we got before.

Collection A-(has only 1 documnet which saves the timestamp)
_id:Properties
Timestamp:ISODate("2019-02-13T06:44:45.387Z")

Collection B-(has multiple documents which get updates all thee time)
But it does not have timestamp field.

I have to pick 'Timestamp' from collection A and retrieve all those documents from Collection B that are added after that timestamp

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Vishal Roy
  • 120
  • 1
  • 10

2 Answers2

1

You can find your data with findByCreatedAtGreaterThan(LocalDateTime oneHourLessFromNow ) where time is one hour less than now.

You can calculate the one hour less time with following code.

LocalDateTime oneHourLessFromNow = LocalDateTime.now().minusHours(1);
Shahzeb Khan
  • 3,582
  • 8
  • 45
  • 79
1
  1. find last timestamp from collectionA
  2. popping timestamp into a fakeObjectId
  3. query collectionB with { _id: { $gt: fakeObjectId} }

This idea comes from this answer, the objectId contains document created time, so we can pop a fake objectId as query filter.

Demo code below:

public class MongoTest {
    public static void main(String[] args) {
        MongoClient client = MongoClients.create();
        MongoDatabase testDb = client.getDatabase("test");
        MongoCollection<Document> collectionA = testDb.getCollection("test");
        MongoCollection<Document> collectionB = testDb.getCollection("runoob");

        Document first = collectionA.find().first();
        Date lastOptTime = first.getDate("lastOptTime");

        ObjectId fakeObjectId = objectIdFromDate(lastOptTime);

        FindIterable<Document> documents =
                collectionB.find(Filters.gte("_id", fakeObjectId));
        for (Document document : documents) {
            System.out.println(document);
        }
    }

    public static ObjectId objectIdFromDate(Date date) {
        long second = date.getTime() / 1000;
        return new ObjectId(String.format("%02x", second) + "0000000000000000");
    }
}
tianzhipeng
  • 2,149
  • 1
  • 13
  • 17
  • Hey, `collectionB.find(Filters.gte("_id", fakeObjectId));` line gives me error saying _"The method find(DBObject) in the type DBCollection is not applicable for the arguments (Bson)"_ – Vishal Roy Feb 13 '19 at 10:01
  • @VishalRoy which version of mongo client do you use? Mine is mongodb-driver-sync 3.10.1 . Maybe older version has different api. – tianzhipeng Feb 13 '19 at 10:17
  • i am using mongo-java-driver-3.8.2 – Vishal Roy Feb 13 '19 at 10:20
  • @VishalRoy mongo-java-driver-3.8.2 also works for me. – tianzhipeng Feb 13 '19 at 10:27
  • yeah it is working for me now. I was using deprecated db instead of MongoDatabase. However my CollectionA has multiple documents . How can i search with a condition like where _id:"abc"? – Vishal Roy Feb 14 '19 at 08:18
  • @VishalRoy I thought you just need to `find()` the last timestamp from collectionA with some filters, I don't know how to filter according to your description. – tianzhipeng Feb 14 '19 at 08:34
  • okay understood. Just one last thing, what is the logic behind objectIdFromDate method – Vishal Roy Feb 14 '19 at 08:36
  • @VishalRoy Because mongo generate objectId by: hex("timestamp") + randomValue1 + randomValue2 + counter + sth, so we can fake a objectId from date, and use this fakeObjectId to filter by create date. see the link i paste above. – tianzhipeng Feb 14 '19 at 08:42