skip to Main Content

What is the best way to find all the documents where objA is the same as objB (order of keys is not important)?

Inspired by another question by @Digvijay, I was looking for a way to compare two objects on MongoDB query and could not find a relevant solution on SO.

Sample data:

[
  {
    objA: {a: 1, b: 2},
    objB: {a: 1, b: 2}
  },
  {
    objA: {m: "g", c: 5},
    objB: {c: 5, m: "g"}
  },
  {
    objA: {m: "g", c: 7},
    objB: {c: 5, m: "g"}
  },
  {
    objA: {m: "g", c: 7},
    objB: {b: "g", c: 7}
  }
]

Expected results:

[
  {
    objA: {a: 1, b: 2},
    objB: {a: 1, b: 2}
  },
  {
    objA: {m: "g", c: 5},
    objB: {c: 5, m: "g"}
  },
]

2

Answers


  1. Maybe use the old-school trick of converting them into an array by $objectToArray. Use $sortArray to sort by key. Compare by the sorted array to get the matches.

    db.collection.aggregate([
      {
        $addFields: {
          "sortedA": {
            $sortArray: {
              input: {
                "$objectToArray": "$objA"
              },
              sortBy: {
                k: 1
              }
            }
          },
          "sortedB": {
            $sortArray: {
              input: {
                "$objectToArray": "$objB"
              },
              sortBy: {
                k: 1
              }
            }
          }
        }
      },
      {
        "$match": {
          $expr: {
            $eq: [
              "$sortedA",
              "$sortedB"
            ]
          }
        }
      },
      {
        "$unset": [
          "sortedA",
          "sortedB"
        ]
      }
    ])
    

    Mongo Playground

    Login or Signup to reply.
  2. You can do it like this:

    • $objectToArray – to transform objA and objB to arrays.
    • $setEquals – to compare if above arrays have the same distinct elements.
    db.collection.aggregate([
      {
        $match: {
          $expr: {
            $setEquals: [
              { $objectToArray: "$objA" },
              { $objectToArray: "$objB" }
            ]
          }
        }
      }
    ])
    

    Working example

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search