peter
peter

Reputation: 257

Mongodb java spring update nested object

Running a java spring project (v2) with mongo v4. Trying to update a nested object and been reading a lot on SO but havent found any good solution.

I have something like the following:

menu {
   id
   name
   categories {
     id
     name
     products {
       id
       price
       referenceProduct {
         id
         name
       }
     }
   }
}

When I update a reference product, then I want all my referenceproducts in menus to be updated as well.

I have tried the following:

Query query = Query.query(Criteria
      .where("menuProductCategories.menuProducts.refProduct.id").is(refProduct.getId())
    );

Update update = new Update().set("menuProductCategories.$.menuProducts.$.refProduct", refProduct);

But then I get the too many positional elements found.

Next idea would be to use arrayfilters using something like the following (just trying to update name prop to 'TEST'):

Bson filter = Filters.eq("menuProductCategories.menuProducts.refProduct.id", new ObjectId(refProduct.getId()));
Bson update = new Document("$set", new Document().append("menuProductCategories.$[i].menuProducts.$[j].refProduct.name", "TEST"));

But then I get stuck on how to specify my arrayfilters since they all assume that you know the index, which I don't since I want to do a full search and update all that matches my initial criteria.

Any ideas? Of course I could just retrieve all the menus and iterate over them, but I would love to find a small neat solution.

Upvotes: 0

Views: 2321

Answers (1)

s7vr
s7vr

Reputation: 75994

You can use below query in 3.6 server version with 3.6.x mongodb driver.

 MongoCollection<Document> collection = mongoTemplate.getDb().getCollection("col");

 Bson update = Updates.set("menuProductCategories.$[].menuProducts.$[i].refProduct.name", "TEST");
 Bson filter = Filters.eq("i.refProduct.id", new ObjectId(refProduct.getId()));
 UpdateOptions updateOptions = new UpdateOptions().arrayFilters(Arrays.asList(filter));

 collection.updateOne(null, update, updateOptions);

Upvotes: 2

Related Questions