Search code examples
pythonmongodbpymongo

MongoDB $indexOfArray not working for a nested object inside an array


I have a document with the following data

{
    "_id": "640311ab0469a9c4eaf3d2bd",
    "id": 4051,
    "email": "manoj123@gmail.com",
    "password": "SomeNew SecurePassword",
    "about": null,
    "token": "7f471974-ae46-4ac0-a882-1980c300c4d6",
    "country": "India",
    "location": null,
    "lng": 0,
    "lat": 0,
    "dob": null,
    "gender": 0,
    "userType": 1,
    "userStatus": 1,
    "profilePicture": "Images/9b291404-bc2e-4806-88c5-08d29e65a5ad.png",
    "coverPicture": "Images/44af97d9-b8c9-4ec1-a099-010671db25b7.png",
    "enablefollowme": false,
    "sendmenotifications": false,
    "sendTextmessages": false,
    "enabletagging": false,
    "createdAt": "2020-01-01T11:13:27.1107739",
    "updatedAt": "2020-01-02T09:16:49.284864",
    "livelng": 77.389849,
    "livelat": 28.6282231,
    "liveLocation": "Unnamed Road, Chhijarsi, Sector 63, Noida, Uttar Pradesh 201307, India",
    "creditBalance": 130,
    "myCash": 0,
    "data": {
        "name": "ThisIsAwesmoe",
        "arr": [
            1,
            100,
            3,
            4,
            5,
            6,
            7,
            8,
            9
        ],
        "hobies": {
            "composer": [
                "anirudh",
                {
                    "co_singer": [
                        "rakshitha",
                        "divagar"
                    ]
                },
                "yuvan",
                "rahman"
            ],
            "music": "helo"
        }
    },
    "scores": [
        {
            "subject": "math",
            "score": 100
        },
        {
            "subject": "physics",
            "score": 85
        },
        {
            "subject": "chemistry",
            "score": 95
        }
    ],
    "fix": 1,
    "hello": 1,
    "recent_views": [
        200
    ],
    "exam": "",
    "subject": "",
    "arr": {
        "name": "sibidharan",
        "pass": "hello",
        "score": {
            "subject": {
                "minor": "zoology",
                "major": "biology",
                "others": [
                    "evs",
                    {
                        "name": "shiro",
                        "inarr": [
                            200,
                            2,
                            3,
                            {
                                "sub": "testsub",
                                "newsu": "aksjdad",
                                "secret": "skdjfnsdkfjnsdfsdf"
                            },
                            4,
                            12
                        ]
                    }
                ]
            },
            "score": 40,
            "new": "not7",
            "hello": {
                "arr": [
                    5,
                    2
                ]
            }
        }
    },
    "name": "Manoj Kumar",
    "d": [
        1,
        3,
        4,
        5
    ],
    "score": {},
    "hgf": 5
}

I am trying to find the $indexOfArray located in this path data.hobies.composer.1.co_singer and I am using the following query:

[
  {
    "$match": {
      "id": 4051
    }
  },
  {
    "$project": {
      "index": {
        "$indexOfArray": [
          "$data.hobies.composer.1.co_singer",
          "divagar"
        ]
      }
    }
  }
]

and this returns -1 with this python code that uses pymongo

result = list(self._collection.aggregate(pipeline))
return result[0]["index"]

whereas the pipeline is the query above.

It is working if there is no array in the nested path, but if there is an array, $indexOfArray returns -1.

What am I missing?


Solution

  • First access the co-singer array using "$ElemAt" on the composer array, and then find index using '$indexofArray'

    db.collection.aggregate([
          {
            "$match": {
              "id": 4051
            }
          },
          {
            "$addFields": {
              "co_singer": {
                $arrayElemAt: [
                  "$data.hobies.composer",
                  1
                ]
              }
            }
          },
          {
            "$project": {
              "index": {
                "$indexOfArray": [
                  "$co_singer.co_singer",
                  "divagar"
                ]
              }
            }
          }
        ])
    

    Check this pipeline, this returns the index correctly Demo @Mongo playground