1

I need to compare two nested arrays with mongo but I'm not really an expert so I need some help on doing that.

Let's say I have a document with an array slots:

[
    [
        {
            "start": 1,
            "end": 2
        }
    ],
    [
        {
            "start": 3,
            "end": 4
        },
        {
            "start": 5,
            "end": 6
        }
    ]
]

And I need to know if another array is a subset of it:

db.collection.aggregate([
  {
    $project: {
      slots: {
        $setIsSubset: [
          [
            [
              {
                start: 1,
                end: 2
              }
            ],
            [
              {
                start: 3,
                end: 4
              },
              {
                start: 5,
                end: 6
              }
            ]
          ],
          "$slots"
        ]
      }
    }
  }
])

This returns true, but if I remove one element in the second sub array, it returns false as the sub array isn't equal anymore.

I thought of doing some kind of $map where I would compare each sub array but I realized I didn't know how to reference the index of the array we're comparing to.

Any ideas? Thanks

Edit : the first level of the stored array and the array we're comparing it with are days of the week so that information needs to be kept.

Online sandbox

1 Answer 1

2

If you consider those nested arrays as days of week you probably need to compare them day by day and check if all "pairs" are subsets. To achieve that you can use $addFields to add your input as another field and then in the next step run $setIsSubset on every day based on index generated by $range operator. If all elements are true ($allElementsTrue) then it means that you specified a subset for every day:

var input = [
    [
        {
        start: 1,
        end: 2
        }
    ],
    [
        {
        start: 5,
        end: 6
        }
    ]
];

db.col.aggregate([
    {
        $addFields: {
            inputArray: input
        }
    },
    {
        $project: {
            isSubset: {
                $allElementsTrue: {
                    $map: {
                        input: { $range: [ 0, { $size: "$slots" } ] },
                        as: "index",
                        in: {
                            $setIsSubset: [
                                { $arrayElemAt: [ "$inputArray", "$$index" ] },
                                { $arrayElemAt: [ "$slots", "$$index" ] }
                            ]
                        }
                    }
                }
            }
        }
    }
])
Sign up to request clarification or add additional context in comments.

11 Comments

Sorry, should have mentioned I can't extract the arrays as their position is significant (it refers to a day of the week). I'll edit the OP.
@MrVoodoo so maybe you could keep slots as the original array but run $setIsSubset on flattened array just to check if subsets match ?
In some cases the check would pass even if it shouldn't. For example Monday has {start: 1, end: 2} and I want to check if Tuesday has {start: 1, end: 2}, it would pass the test.
@MrVoodoo I see, modfied my answer
Why are you asking about that Actually one of my colleague has gotten two wonderful gift hampers(containing two mugs, t-shirts, bottles and much more) from the stackoverflow. She has participated in some contest on the stackoverflow I don't know much about that but she has. I read about that on metaexchange and learned that SO rewards that on 100k reps but she has only 1k. So I wanted to know whether I m missing something. BTW Thank you
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.