How to update computed dynamic field in mongo?

127
February 13, 2018, at 5:07 PM

Let's say I am receiving statements from third party system, each statements have multiple pages, pages order is not guranteed, each page will have a page number and the last page will have a field lastPage = 'Y',

On receiving each page I make an entry into pages collection

For example, here we have for statement a, 5 pages received, only the 5th page will have lastPage yes and the pages order is not gurnateed

{
    page : 1,
    statement : 'a',
    lastPage : 'no',
    data : 'some'
},
{   
    page : 5,
    statement : 'a',
    lastPage : 'yes',
    data : 'some'
},
{
    page : 4,
    statement : 'a',
    lastPage : 'no',
    data : 'some'
},
{
    page : 2,
    statement : 'a',
    lastPage : 'no',
    data : 'some'
},
{
    page : 3,
    statement : 'a',
    lastPage : 'no',
    data : 'some'
}

while inserting pages I do an upsert meta info (page number and last page) into another collection statements

after receiving page 1

{
    statement : 'a',
    ready : 'no', // no, last page not received
    pages : [1] 
}

after receiving page 5

{
    statement : 'a',
    ready : 'yes', // no, pages.length != lastPage
    pages : [1,5],
    lastPage : 5
}

after receiving all pages

{
statement : 'a',
updated : ''
ready : 'yes', // yes, lastPage received && pages.length === lastPage
pages : [1,5,4,2,3],
lastPage : 5
}

Once I received all pages my statement is ready to process, how can I mark the field ready to Y when lastPage exits && pages.length === lastPage while doing the upsert?

here is my java code

    Bson filter = Filters.eq("statement", "a");
    Document set = new Document("updated", new Date()); // append("lastPage", lastPageNo); if exists in page
    Document push = new Document("pages", pageNo);
    Document update = new Document("$set", set).append("$push", push);
    FindOneAndUpdateOptions options = new FindOneAndUpdateOptions();
    options.upsert(true);
    options.returnDocument(ReturnDocument.AFTER);
    Document updated = collection.findOneAndUpdate(filter, update);

after every upsert am doing below check explicitly, is there a way to do this check part of upsert itself?

    if (updated.containsKey("lastPage") && updated.containsKey("pages")) {
        int lastPage = (Integer) updated.get("lastPage");
        List<Integer> pageNos = (List<Integer>) updated.get("pages");
        boolean allPagesReceived = IntStream.rangeClosed(1, lastPage).allMatch(pageNos::contains);
        if (allPagesReceived) {
            Document ready = new Document("ready", true);
            collection.findOneAndUpdate(filter, new Document("$set", ready));
        }
    }

how can I ask mongo to compute the pre checks and update ready field?

READ ALSO
I get an error Ding when I click a line number in Netbeans

I get an error Ding when I click a line number in Netbeans

I tried clicking one of the error markers and I got the ding noise and nothing happens

132
Is there a way to validate json attributes based on predefined values in java?

Is there a way to validate json attributes based on predefined values in java?

Is there a way to validate json attributes based on predefined values in java?

79
Java ArrayList String Comparator

Java ArrayList String Comparator

I want to check if a String variable is equal to some String variable that is inside an ArrayListWithout using iterator, for, for each

167