简体   繁体   中英

Checking for Differences Between Docs in Array Embedded Within Another Array

I am trying to compare two documents (actually the current and previous version of the same record), to determine if the contents of an array on the root of the documents is different. But what I'm specifically looking for are changes on an embedded array within that root array.

My document structure looks something like this:

{
  _id: 1,
  name: { 
    first: "John",
    last: "Smith"
  },
  services: [
    { 
      service: "serviceOne",
      // I want to detect differences at this "history" array level
      history: [ 
        { 
          _id: <ObjectId>,
          title: value
        },
        { 
          _id: <ObjectId>,
          title: value
        }
      ]
    },
    { 
      service: "serviceTwo",
      history: [
        { 
          _id: <ObjectId>,
          title: value
        },
        { 
          _id: <ObjectId>,
          title: value
        }
      ]
    },
  ]   
}

How can I check to see if there are differences between the two documents at the level of the "history" array?

Compare the _id and title of all of them:

const compare = cb => (a, b) => a.length === b.length && a.every((el, i) => cb(el, b[i]));
const take = (key, cb) => (a, b) => cb(a[key], b[key]);

const equal = take("services", compare(
  take("history", compare(
    (a, b) => a._id === b._id && a.title === b.title
  ))
))(obj, obj2);

Or if the formatting (order of keys) doesn't change between two versions, it can be simplified to:

 JSON.stringify(obj) === JSON.stringify(obj2)

You could use this:

function compareObjects(obj1,obj2,reversed){
    for(var key in obj1){
        if(typeof obj2[key]=="undefined") return false
        if(typeof obj1[key] == "object"){
            if(!compareObjects(obj1[key],obj2[key])) return false
        }
        else if(obj1[key]!=obj2[key]) return false
    }
    return reversed ? true : compareObjects(obj2,obj1,true)
}

via

var new_history = new_document.services.map(service=>service.history)
var old_history = old_document.services.map(service=>service.history)
var are_identical = compareObjects(new_history,old_history)

It will look recursively for differences, regardless of the structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM