Search code examples
javamongodbmongo-java-drivermongo-collection

Trying to update a document using MongoDB Java Driver


Thank you

  • I just want to thank you for clicking on this question! I've tried my best to make this as thorough as possible.
  • but still, feel free to let me know if you need to clarify anything further!
  • if you think the question is too long. you can just read the third & fourth part and post your own solution down here!

Setup

  • Mongodb Java driver: org.mongodb:mongo-java-driver:3.11.0-rc0

What I want to do

  • find a specific document with a specific "name" field.
  • then update the other field or the whole document.

Example Document

// the document that I am trying to find in db
{
  "_id":"5de6af7cfa42833bd9849477",
  "name":"Richard Koba",
  "skills":[]
}

// the document that I have
{
  "name":"Richard Koba",
  "skills":[jump, dance, sing]
}

// final result in db
{
  "_id":"5de6af7cfa42833bd9849477",
  "name":"Richard Koba",
  "skills":[jump, dance, sing]
}

What I am doing now

  // finding a document with same "name" field as input doc and update it with doc
  public MongoCollection updateDocument(Document doc, String colName) {
    MongoCollection collection;

    // make sure collection exist
    try {
      collection = connectCollection(colName); // returns MongoCollection Obj
    } catch (CollectionNotFoundException e) {
      MessageHandler.errorMessage(e.getMessage());
      return null;
    }

    // trying to find the document.
    if (collection.find(eq("name", doc.get("name"))).first() == null) {
      // if document not found, insert a new one
      collection.insertOne(doc);
    } else {
      // if the document found, replace/update it with the one I have
      collection.replaceOne(eq("name", doc.get("name")), doc);
    }

    return collection;
  }

What I found about my false solution

  1. collection.find(eq("name", doc.get("name"))).first() never returns null.
  2. Java only tells me it returns an Object. MongoDB Documentation tells me it is a TResult, which point back to MongoIterable<TResult>. I am stuck here.
  3. the code outcome is that none of the documents is inserted/updated in the end.

Reference


Solution

  • I tried some code and this works fine. This is not much different from your code.

    Created a document from mongo shell:

    MongoDB Enterprise > db.users.findOne()
    {
            "_id" : "5de6af7cfa42833bd9849477",
            "name" : "Richard Koba",
            "skills" : [ ]
    }
    

    My Java Code:

    // Test input documents
    private Document doc1 = new Document()
                               .append("name", "Richard Koba")
                               .append("skills", Arrays.asList("jump", "dance", "sing"));
    private Document doc2 = new Document()
                                .append("name", "Richard K")
                                .append("skills", Arrays.asList("sings"));
    

    When doc1 is passed to the following method the result is: "### Doc FOUND". And, with doc2 the result is "### Doc NOT found".

    private void checkDocument(Document doc) {
    
        MongoClient mongoClient = MongoClients.create("mongodb://localhost/");
        MongoDatabase database = mongoClient.getDatabase("javadb");
        MongoCollection<Document> collection = database.getCollection("users");
    
        if (collection.find(eq("name", doc.get("name"))).first() == null) {
    
            System.out.println("### Doc NOT found");
        } 
        else {
            System.out.println("### Doc FOUND");
        }
    }
    

    I also tried this, with the same results.

    Document d = collection.find(eq("name", doc.get("name"))).first();
    if (d == null) { // ... }
    

    I also tried this; works fine too.

    if (collection.find(queryFilter).iterator().tryNext() == null) { // ... }
    


    I think there might be some other issue with your code or the database / collection. Some debugging and testing with new data might reveal the real issue.

    • Did you check if the document already exists in the collection, from mongo shell or Compass tools?
    • Are you using the right database and collection names?
    • After each test run are you verifying the data in the database if it is updated / inserted?



    collection.find(eq("name", doc.get("name"))).first() never returns null.

    With the code I posted above, the find query did return null when the users collection was empty.