Search code examples
javascriptmongodbmeteorobservers

How to propagate changes made to one doc, on to other related documents in mongodb


I have a meteor app where which has an observer to help detect any changes to one particular document. How do I propagate changes done to that doc, to other related documents without having to write multiple generic queries?

What I have:

orgPolicy:

{
    "_id" : "uudY4ekaZ4tPpN7KN",
    "organizationName" : "combat wombat systems 2",
    "priorityIP" : "2.2.2.2,6.6.6.6/24",
    "blacklistedServers" : "3.3.3.3",
    "policyType" : "orgLevelPolicy",

}

DeptLevelPolicy:

{
    "_id" : "Fb75pKgvePxakKTi4",
    "organizationName" : "combat wombat systems 2",
    "departmentName" : "mighty moose",
     "useOrgPolicyValuesForPriorityIp" : true,
    "priorityIP" : "2.2.2.2,6.6.6.6/24",
    "useOrgPolicyValuesBlacklistedServers" : true,
    "blacklistedServers" : "3.3.3.3",
    "policyType" : "departmentLevelPolicy",
}

What I need to do

If the orgLevelPolicy document changes, then only update those deptLevelPolicy docs which have the field's respective boolean flag set to true

Eg.

If orgLevelPolicy.priorityIP changes, then only update the field of deptLevelPolicy.priorityIP of those deptLevelPolicy, whose useOrgPolicyValuesBlacklistedServers is set to true

I have a crude observer such as below, but any change to the orgPolicy will triger a multitude of changes to all deptLevelPolicy irrespective of the fact that their bool flag is set, or if the field has even changed at all.

(I hope my explanation is making any sense. Please let me know if I need to make any changes to better illustrate the scenario)

 Meteor.startup(() => {

     var cursor = policies.find({
         policyType: "orgLevelPolicy"
     });

     var handle = cursor.observe({
         changed: function(orgLevelPolicyChanged) {
             console.log("Updating: departmentLevelPolicy: priorityIP");
             policies.update({policyType:"departmentLevelPolicy","useOrgPolicyValuesForPriorityIp": true},{$set:{priorityIP: orgLevelPolicyChanged.priorityIP, organizationName: orgLevelPolicyChanged.organizationName}},{multi:true});
             console.log("Updating: departmentLevelPolicy: blacklistedServers");
         },

     });
 });

Solution

  • You should be pretty close but you're trying to match the parent organization in your modifier instead of your query.

    Do the name matching in the first argument to .update() (the query) instead of the second (the modifier)

    const handle = cursor.observe({
      changed(orgLevelPolicyChanged) {  
        policies.update(
          {
            policyType: "departmentLevelPolicy",
            useOrgPolicyValuesForPriorityIp: true,
            organizationName: orgLevelPolicyChanged.organizationName
          },
          { $set:
            {
              priorityIP: orgLevelPolicyChanged.priorityIP,
            }
          },
          { multi:true }
        );
      },
     });