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"}
},
]
CodePudding user response:
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" }
]
}
}
}
])
CodePudding user response:
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"
]
}
])