Search code examples
javamongodbbson

MongoDB Search nested Objects without knowing Key


I have a list of objects that are given somewhat arbitrary Object keys as a result of using the async Java driver + BSON.

enter image description here

My issue is given the fact that jobStatuses are an arbitrary list of Dictionary items where I don't know the key, I have no idea how to access its sub-values. In the end, I'm trying to build a query that returns if ANY of jobStatus.*._id are true given a list of potential Object ID's.

So I'd be giving a list of ID's and want to return true if ANY of the items in jobStatuses have any of the given ID's. Any ideas?


Solution

  • Let's try this :

    db.yourCollectionName.aggregate([
        {
            $project: {
                _id: 0,
                jobStatutses: { $arrayElemAt: [{ $objectToArray: "$jobStatutses" }, 0] }
            }
        }, {
            $match: { 'jobStatutses.v._id': { $in: [ObjectId("5d6d8c3a5a0d22d3c84dd6dc"), ObjectId("5d6d8c3a5a0d22d3c84dd6ed")] } }
        }
    ])
    

    Collection Data :

    /* 1 */
    {
        "_id" : ObjectId("5e06319c400289966eea6a07"),
        "jobStatutses" : {
            "5d6d8c3a5a0d22d3c84dd6dc" : {
                "_id" : ObjectId("5d6d8c3a5a0d22d3c84dd6dc"),
                "accepted" : "123",
                "completed" : 0
            }
        },
        "something" : 1
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5e0631ad400289966eea6dd1"),
        "jobStatutses" : {
            "5d6d8c3a5a0d22d3c84dd6ed" : {
                "_id" : ObjectId("5d6d8c3a5a0d22d3c84dd6ed"),
                "accepted" : "456",
                "completed" : 0
            }
        },
        "something" : 2
    }
    
    /* 3 */
    {
        "_id" : ObjectId("5e0631cd400289966eea7542"),
        "jobStatutses" : {
            "5e06319c400289966eea6a07" : {
                "_id" : ObjectId("5e06319c400289966eea6a07"),
                "accepted" : "789",
                "completed" : 0
            }
        },
        "something" : 3
    }
    

    Output :

    /* 1 */
    {
        "jobStatutses" : {
            "k" : "5d6d8c3a5a0d22d3c84dd6dc",
            "v" : {
                "_id" : ObjectId("5d6d8c3a5a0d22d3c84dd6dc"),
                "accepted" : "123",
                "completed" : 0
            }
        }
    }
    
    /* 2 */
    {
        "jobStatutses" : {
            "k" : "5d6d8c3a5a0d22d3c84dd6ed",
            "v" : {
                "_id" : ObjectId("5d6d8c3a5a0d22d3c84dd6ed"),
                "accepted" : "456",
                "completed" : 0
            }
        }
    }
    

    All you need is to check if at least one doc gets returned from DB for a given list or not, So we don't need to worry about document structure then just do result.length in your code to say at least one doc got matched for the input list.