5

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?

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Sweet! This seems to work to do the matching properly. How do I then return the whole document as the result, rather than just the data of jobStatuses?
@Cryptite : Do you need whole document as is from DB ? That case this operation might become a bit bulky, It's ok depends on your collections data & indexes - give it a try - If it's needed then in $project stage remove _id & also replace $project with $addFields & replace jobStatutses with jobStatutsesArr & atlast add third stage $project to remove jobStatutsesArr. Result would seem pretty much same like your original docs !!

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.