Help required on Array update and encryption

Hi,

We have a document like

{
    "_id" : "DocumentID",
    "mobileNo" : "123456789",
    "productId" : "XPL",
    "applicantsDetail" : [ 
        {
            "customerId" : "58994",
            "applicant" : {
                "applicantType" : "PRIMARY",
                "firstName" : "xyz",
                "lastName" : "xyz",
                "gender" : "MALE",
                "dateOfBirth" : ISODate("1976-05-22T00:00:00.000Z"),
                "countryOfBirth" : "xyz",
                "salutation" : "MR",
                "mobileNo" : "123456789",
                "emailId" : "xyz@hotmail.com",
          
                "currentAddress" : {
                    "addressType" : "xyz",
                    "addressCategory" : "xyz",
                    "buildingNumber" : "211",
                    "street" : "street",
                    "addressLine1" : "211",
                    "city" : "xyz",
                    "stateCode" : "xyz",
                    "country" : "xyz",
                    "postalCode" : "xyz"
                }
                "maritalStatus" : "SINGLE",
                "occupationType" : "SEP",
                "incomeContributor" : false,
                "propertyOwner" : false
            }
        },

        {
            "customerId" : "58995",
            "applicant" : {
                "applicantType" : "PRIMARY",
                "firstName" : "xyz",
                "lastName" : "xyz",
                "gender" : "MALE",
                "dateOfBirth" : ISODate("1976-05-22T00:00:00.000Z"),
                "countryOfBirth" : "xyz",
                "salutation" : "MR",
                "mobileNo" : "123456789",
                "emailId" : "xyz@hotmail.com",
          
                "currentAddress" : {
                    "addressType" : "xyz",
                    "addressCategory" : "xyz",
                    "buildingNumber" : "211",
                    "street" : "street",
                    "addressLine1" : "211",
                    "city" : "xyz",
                    "stateCode" : "xyz",
                    "country" : "xyz",
                    "postalCode" : "xyz"
                }
                "maritalStatus" : "SINGLE",
                "occupationType" : "SEP",
                "incomeContributor" : false,
                "propertyOwner" : false
            }
        }
    ],
    "auditTrailInformation" : {},
    "createdDate" : ISODate("2021-08-24T17:57:06.119Z"),
    "entityType" : "INDIVIDUAL",
    "firstName" : "xyz",
    "lastName" : "xyz",
    "lastUpdateDate" : ISODate("2021-08-24T17:57:22.367Z"),
    "partnerApplicantId" : "XPL",
    "status" : "RECEIVED"
}

Here, if we see that we have a field called applicantsDetail which is of array type. The identifier which uniquely identifies the document in array is customerId.

Problem 1

We are getting different kind of queries for update purpose.

  1. An update may come on fields which are not in applicantsDetail level, but at the top level fields like update on auditTrailInformation, partnerApplicantId etc.
  2. Update may come for array elements that too in a partial manner like we want to update emailId of applicant with customerId “58995” etc. Applicant object contains lot of fields.
  3. A new applicant may come which is not existing in the list, we need to append that.
  4. A update may combine all the above type of updates mentioned in point 1,2,3. Eg update needs to be done on auditTrailInformation and applicant level for a customer.

Currently i am updating the record via splitting the update query in two levels.

Firstly i am updating the attributes at the top level like updating auditTrailInformation etc. And then updating applicantsDetail via using Arrayfilters.

So as we see there are two queries needed for this. Is there a way in which we can achieve this in a single go.

Problem 2

Apart from that applicant contains large number of fields, which may increase in future. And when the update request is coming to me then, i need to check manually which fields are there for which we need to make an update, for forming the $set. we are doing this in spring boot java, so we have to write logic like

 if (Objects.nonNull(record.getEmailId())) {
      update.set("businessInformation", record.getEmailId());
 } 

So, due to large number of fields it is difficult to write and maintain such code.

Is there a way in which we can merge the updated fields with the existing record in the DB, so that we can avoid such code.

Problem 3
We are going to soon implement CSFLE, and for that there we need some attributes to be encrypted in an deterministic manner in our applicantsDetail* array , which currently Mongo does not support on array. Can you suggest what should we do here. We need deterministic encryption at-least on customerId, as that is used in update Query. Should we use linking or a manual reference here rather than embedding ? In read request we need applicantsDetail array, so lazy loading will not work for us, that was the reason we went with embedding. Our array on an average will have 3 applicants.

Please reply if something is unclear in the problem statements, will try to clarify that more.