0

I have only one collection in my Mongodb and that is as follows

[
    {
        "_id": {
            "timestamp": 1626753855,
            "date": "2021-07-20T04:04:15.000+00:00"
        },
        "metadata": [
            {
                "country": "Canada",
                "authors": [
                    {
                        "author": "Test Author",
                        "Books": [
                            {
                                "name": "Sample Book",
                                "code": "JCAR"
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

The method I am using is as follows

    private void updateAuthorsMetadata(AuthorMetadata authorMetadata) {
        MongoCollection<Document> collection = mDatabase.getCollection(authorMetadataCollection);

        Bson eqFilter = eq("metadata.country", "Canada");
        FindIterable<Document> itrDoc = collection.find(eqFilter);
        if (itrDoc.first() == null) {
            Document document = new Document();
            document.append("metadata",
                    Arrays.asList(new Document("country", authorMetadata.getCountry()).append("authors",
                            Arrays.asList(new Document("author", authorMetadata.getAuthorName()).append("Books",
                                    Arrays.asList(new Document("name", authorMetadata.getBookName()).append("code",
                                            authorMetadata.getBookCode())))))));

            collection.insertOne(document);
        } else {
            Bson andFilter = and(eq("metadata.country", "Canada"),
                    eq("metadata.authors.author", "John Doe"));
                    
            FindIterable<Document> itrAndDoc = collection.find(docFilter);

            if (itrAndDoc.first() == null) {
                Document doc = new Document("author", "John Doe).append("Books",
                        Arrays.asList(new Document("name", "Some Book").append("code",
                                "SBD4")));
                Bson update = push("metadata[].authors", doc);

                UpdateResult result = collection.updateOne(eqFilter, update);
            } 
        }
}

The issue I am facing is that when I update collection at

else block

then it is adding the document to the root instead of adding it to the authors array, as shown in the image below.

enter image description here

How I can update it at the proper location i.e. adding to "authors" array? I am using Java driver v-3.12.7.

Karan
  • 752
  • 2
  • 13
  • 34
  • shouldn't it be `if (itrAndDoc.first() != null)`? – Vivek Bani Jul 20 '21 at 15:05
  • No, as I am adding a new author to the authors array. if (itrAndDoc.first() != null) means there is already an Author present in same country with same name. I will add this condition later after I atleast add new author. – Karan Jul 20 '21 at 15:12

1 Answers1

0

Finally, I figured it out. Anyone out there struggling with same issue can refer to this method. The issue was positional operators, some forums says that multiple positional operators can't be used below v 3.x.x but I am using 3.12.x and still had this issue. I think the way I am doing is not best/optimal but it works and if anyone direct me to the right direction then it would be great.

private void updateAuthorMetadata(AuthorMetadata authorMetadata) {
        MongoCollection<Document> collection = mDatabase.getCollection(authorMetadataCollection);

            Bson bsonEqFilter = eq("metadata.country", authorMetadata.getCountry());
            FindIterable<Document> itrDoc = collection.find(bsonEqFilter);

            Document found = itrDoc.first();
            if (found == null) {
                Document document = new Document();
                document.append("metadata",
                        Arrays.asList(new Document("country", authorMetadata.getCountry()).append("authors",
                                Arrays.asList(new Document("author", authorMetadata.getAuthor()).append("books",
                                        Arrays.asList(new Document("name", authorMetadata.getBookName())
                                                .append("code", authorMetadata.getBookCode())))))));

                collection.insertOne(document);
            } else {
                Bson bsonAndFilter = and(eq("metadata.country", authorMetadata.getCountry()),
                        eq("metadata.authors.author", authorMetadata.getAuthor()));

                FindIterable<Document> itrAndDoc = collection.find(bsonAndFilter);

                if (itrAndDoc.first() == null) {
                    Document document = new Document("author", authorMetadata.getAuthor()).append("Books",
                            Arrays.asList(new Document("name", authorMetadata.getBookName()).append("code",
                                    authorMetadata.getBookCode())));

                    Bson update = push("metadata.$.authors", document);

                    UpdateResult result = collection.updateOne(bsonEqFilter, update);

                } else {
                    Bson bsonMoreAndFilter = and(eq("metadata.country", authorMetadata.getCountry()),
                            eq("metadata.authors.author", authorMetadata.getAuthor()),
                            eq("metadata.authors.books.code", authorMetadata.getBookCode()));

                    FindIterable<Document> itrMoreAndDoc = collection.find(bsonMoreAndFilter);

                    if (itrMoreAndDoc.first() == null) {
                        Document docBooks = new Document("name", authorMetadata.getBookName()).append("code",
                                authorMetadata.getBookCode());

                        Bson update = push("metadata.0.authors.$.books", docBooks);

                        UpdateResult result = collection.updateOne(bsonAndFilter, update);
                    }
                }
            }
}
Karan
  • 752
  • 2
  • 13
  • 34