My Watcher detects replace when document is updated by mongoDB compass but not with findOneAndReplace

This watcher that I coded (using Android app coded with java ) will detect an update using MongoDB compass but not when I run the same update from a function using a http endpoint from postman.

I don’t know why. Any help would be appreciated, Thanks.

RealmEventStreamAsyncTask<RealmLogEntry> watcher3 = mongoCollection
                        .watchWithFilterAsync(new Document("fullDocument.userId", "18"));
                watcher3.get(result3 -> {
                    try {
                        if (result3.isSuccess()) {
                            Log.v("EXAMPLE", "Event type watcher 3: " +
                                    result3.get().getOperationType() + " full document: " +
                                    result3.get().getFullDocument());
                        } else {
                            Log.e("EXAMPLE",
                                    "failed to subscribe to filtered changes in the collection with : ",
                                    result3.getError());
                        }
                    } catch (NullPointerException npe) {
                        Log.d(TAG, "onCreate: potential delete by  frig ???????");
                    }
                });

the function that I am running, that is not being detected by the watcher is :

return collection.findOneAndReplace(query, replacement, options)
            .then(replacedDocument => {
                if(replacedDocument) {
                    console.log(`Successfully replaced the following document: ${replacedDocument}.`);
                    response.setStatusCode(200); // Set an HTTP Status code like "201 - created"
                    response.setBody(JSON.stringify({  "code": 200, "message": "update ok", "timestamp": dateBob }));
                } else {
                    console.log("No document matches the provided query.")
                    response.setStatusCode(400); // Set an HTTP Status code like "201 - created"
                    response.setBody(JSON.stringify({  "code": 400, "message": "update error A", "timestamp": dateBob }));
                }
                // return updatedDocument
            })
            .catch(err => {
                    console.error(`Failed to find and replace document: ${err}`)
                    response.setStatusCode(400); // Set an HTTP Status code like "201 - created"
                    response.setBody(JSON.stringify({  "code": 400, "message": "update error B", "timestamp": dateBob }));
                }
            )

How are you setting up your watcher? Is it watching on all event types? And are you specifying the FullDocumentLookup field? See here: https://www.mongodb.com/docs/manual/changeStreams/#lookup-full-document-for-update-operations

The difference is likely that using Data Explorer synthesizes “Replace” events but findOneAndUpdate() synthesizes an “Update” event which will not have the FullDocument field unless you ask for it

Please share replacedDocument.

More or less the output line produced by

console.log(`Successfully replaced the following document: ${replacedDocument}.`);

Sorry, but its unhelpful.

"Successfully replaced the following document: [object Object]."

You seem to already know about

try with it.

I’ve change the function to a replaceOne to simplify:

one document was matched and updated, as expected.
It is not being detected by the watcher.


exports = async function (request, response) {
    const bodyJson = JSON.parse(request.body.text());
    console.log("json body = ", bodyJson);
    const query = {_id: BSON.ObjectId(bodyJson._id)}

    console.log("query = ", bodyJson._id);
    dateBob = new Date();

    // Replace it with a new document
    // const replacement = {
    //     "expire_log": dateBob,
    //     "locfrom" : "deleted",
    //     "remarks" : "deleted"
    // };
     
     
     const replacement = {
        "locfrom" : "deleted",
        "remarks" : "deleted"
     };
     

    try{
        response.addHeader("Content-Type", "application/json"); // Modify the response headers
        const collection = context.services.get("mongodb-atlas").db("logitxp").collection("log-entries");

        // Return the original document as it was before being replaced
        // const options = { "returnNewDocument": false };
        
        

        return collection.replaceOne(query, replacement)
            .then(replacedDocument => {
                if(replacedDocument) {
                    console.log("Successfully replaced the following document: replacedDocument = " + JSON.stringify(replacedDocument));
                    response.setStatusCode(200); // Set an HTTP Status code like "201 - created"
                    response.setBody(JSON.stringify({  "code": 200, "message": "update ok", "timestamp": dateBob }));
                } else {
                    console.log("No document matches the provided query.")
                    response.setStatusCode(400); // Set an HTTP Status code like "201 - created"
                    response.setBody(JSON.stringify({  "code": 400, "message": "update error A", "timestamp": dateBob }));
                }
                // return updatedDocument
            })
            .catch(err => {
                    console.error(`Failed to find and replace document: ${err}`)
                    response.setStatusCode(400); // Set an HTTP Status code like "201 - created"
                    response.setBody(JSON.stringify({  "code": 400, "message": "update error B", "timestamp": dateBob }));
                }
            )
    }
    catch (e) {
        console.log("catch e: ",e);
        response.setBody(JSON.stringify({  "code": 400, "message": "update error C", "timestamp": dateBob }));
    }
}


Logs:
[
  "query =  6282099a7f1e25def6383b49",
  "Successfully replaced the following document: replacedDocument = {\"matchedCount\":1,\"modifiedCount\":1}"
]
{
  "name": "log_replace_expire"
}

You have a watcher that filters

and you do a replaceOne with

I think that is why you watcher is not called. Your replacement document does not have a field named userId that contains the string value 18.

Bingo , that worked !!!

you are a star, thank you so much :grinning: :grinning: :grinning: :trophy: :star:

I’m guessing the compass update was detected because the entire document was updated.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.