2

I've got an endpoint that takes a document ID, and the an Employee object in a nested array that I'd like to have updated. This is working fine. I tried to modify the endpoint to take more than 1 Employee and have it update them all at once, but I can't get it to work. I'm not sure if I've got the format wrong, or it's not possible.

To elaborate, my Census is an already existing object as follows, with 10 Employees in a list:

{
  "id": <ID>
  ...
  "employeeList": [
  {
    "employeeId": <Employee_ID>,
    ...
  }
  ...
  ]
}

I want to update an existing Employee with some new information. So I use the mongo Document ID to find the document, and then find the correct Employee in the list by its EmployeeID. I have it working with something like this for a single Employee update:

Query query = new Query().addCriteria(new Criteria("id").is(id))
      .addCriteria(new Criteria("employeeList.employeeId").is(employee.getEmployeeId());
update.set("employeeList.$", employee);

UpdateResult result = mongoTemplate.updateFirst(query, update, Census.class);

When I tried to update it to do them all at once, that didn't work. I realize now my approach doesn't really make sense so I won't post it (basically surrounding the .addCriteria and the update.set in a for loop to do it for each Employee in the provided list). Got an error like: "Due to limitations of the com.mongodb.BasicDocument, you can't add a second 'employeeList.employeeId' criteria".

Can I do it? Is the only other option to just update this document multiple times in a row? I think it's better to do that than calling the endpoint X times. I'm on Mongo 3.6 in case that affects any answers. TIA.

DFW
  • 805
  • 1
  • 8
  • 18
  • I found the best solution here: [link](https://stackoverflow.com/a/69258976/16649714). Using `new Update().filterArray(...)`. – cheladon Jan 23 '23 at 16:08

3 Answers3

0

sorry but your post is not clear. You display array field EmployeeList - are you trying to add a value to the array? of a single document or all documents?

if not adding a value to this existing array field - then instead are you seeking to add a new field to all documents?

Cahaba Data
  • 624
  • 1
  • 4
  • 4
  • No, I think in that case I would be using the update.push. I'm trying to use the $set to take an existing Employee by its EmployeeID and update it with some new information (ie: name, etc). – DFW Feb 11 '20 at 13:30
0

here is an example of an update of the field: poster for the selected title:

db.movieDetails.updateOne(

{title: "The Martian"},
{$set:{poster: "http://ia.media-etc."}}

There's also the updateMany You should check out Mongo's online manual....

Cahaba Data
  • 624
  • 1
  • 4
  • 4
  • kind of had editing problems on that - it should be all one set of code with a closing ) – Cahaba Data Feb 12 '20 at 13:46
  • This is not Java code using MongoTemplate (or some other package included with spring boot). Nor does it answer my question about updating multiple array objects at the same time with the $set operator. – DFW Feb 12 '20 at 21:46
0

I was unable to find any other answer to my question. So I ended up changing it to a bulk update approach:

BulkOperations bulkOps = mongoTemplate.bulkOps(BulkMode.UNORDERED, Census.class);
for(Employee employee : employeeList) {
    Query query = new Query().addCriteria(new Criteria("id").is(id));
    Update update = new Update().set("employeeList.$", employee);
    bulkOps.updateOne(query, update);
}
BulkWriteResult results = bulkOps.execute();

It doesn't really solve the question about trying to update the same document multiple times, but it works for me for now.

DFW
  • 805
  • 1
  • 8
  • 18