0

I need to switch a Collection.find(demandObject) query to a Collection.aggregate() function and i can't get things together correctly.

My Collection:

    "movies": [
        {
            "_id": "5e34800b13ad37006c550182",
            "name": "Matrix",
            "genres": [
                "5e2d8a3e503465004beeeb4d",
                "5e2d8a3e503465004beeeb4e",
                "5e2d8a3e503465004beeeb55"
            ],
            "themes": [
                "5e2ddd90783eeb0102da66cd"
            ]
        },
        {
            "_id": "5e34800b13ad37006c550182",
            "name": "Matrix 2",
            "genres": [
                "5e2d8a3e503465004beeeb4f",
                "5e2d8a3e503465004beeeb44",
                "5e2d8a3e503465004beeeb56"
            ],
            "themes": [
                "5e2ddd90783eeb0102da66c7"
            ]
        },
    ]

I have the following query:

Collection.find({
    "genres": {
        "$all": [
            "5e2d8a3e503465004beeeb4e",
            "5e2d8a3e503465004beeeb4a"
        ]
    },
    "themes": {
        "$all": "5e2ddd90783eeb0102da66be"
    },
    "name": {
        "$regex": "Matrix",
        "$options": "i"
    }
});

My approach

Collection.aggregate([
    { "$match": 
        { 
            "$and": [
                {"name": { "$regex": "Matrix", "$options": "i" }},
                {"themes": { "$all": ["5e2ddd90783eeb0102da66be"] }},
                {"genres": { "$all": ["5e2d8a3e503465004beeeb4e", "5e2d8a3e503465004beeeb4a"] }}
            ]
        }
    }
]).exec();

The find method returns the collection how i want but the aggregation method response is always empty. What am i doing wrong?

kratze
  • 186
  • 2
  • 11
  • **(1)** When using the [$match](https://docs.mongodb.com/manual/reference/operator/aggregation/match/index.html) stage, the same syntax and format applies as with the `find` query. So, use the same syntax for the conditions and you will get the same results. **(2)** The [$all](https://docs.mongodb.com/manual/reference/operator/query/all/index.html) operator is used with an _array_; your `find` query has the fields `themes` and `perspectives` using it with a string. – prasad_ Apr 07 '20 at 01:46
  • Thank you for your response but it also doesn't match. I edited my approach. – kratze Apr 07 '20 at 08:41
  • The "Matrix" and "Matrix 2" are two documents _or_ just one document with two sub-documents? – prasad_ Apr 07 '20 at 09:34

1 Answers1

0

Meanwhile i found the solution.

First of all @prasad_ was right, the query is exactly the same as in the .find method. In the aggregate method the query is just a bit more strict with the accepted values.

I was trying to match ObjectId's but the aggregate method doesn't understand that those strings are ObjectId's so you have to convert them firstly

new mongoose.Types.ObjectId("5e2ddd90783eeb0102da66be")

And the query works without $and

 Game.aggregate([
                { "$match": {
                    "genres": {
                        "$all": [
                            "5e2d8a3e503465004beeeb4e",
                            "5e2d8a3e503465004beeeb4a"
                        ]
                    },
                    "themes": {
                        "$all": "5e2ddd90783eeb0102da66be"
                    },
                    "name": {
                        "$regex": "Matrix",
                        "$options": "i"
                    }
                }}
            ]);

I found a related answer Can't use $match with mongoose and the aggregation framework

kratze
  • 186
  • 2
  • 11