0

I am trying to find if type=conv is present in given rs , which is present in d --> ds --> rs --> type.

DOCUMENT

{
    "_id" : ObjectId("5ec25873bd796ff191e695b1"),
    "c_name" : "c1",
    "t_name" : "t1",
    "d" : [ 
        {
            "name" : "d1",
            "ds" : [ 
                {
                    "name" : "ds1",
                    "rs" : [ 
                        {
                            "type" : "conv"
                        }
                    ]
                }
            ]
        }, 
        {
            "name" : "d2",
            "ds" : [ 
                {
                    "name" : "ds2",
                    "rs" : []
                }
            ]
        }
    ]
}

QUERY:


filter = {
    "$and": [
        {"c_name": {'$eq': 'c1'}},
        {"t_name": {'$eq': 't1'}},
        {"d.name": {'$eq': 'd2'}},
        {"d.ds.name": {'$eq': 'ds2'}},
        {"d.ds.rs.type": {'$eq': 'conv'}}

    ]
}

OUTPUT

It is returning me document, i guess it is looking for presence of type = conv in full document, even though it is not present on ds2 ( part of d2), but present on ds1 ( part of d1).

Do we have simpler way to find if it exists or not, I would like to first find and then using array filters , we can update the specific element inside deeply nested array.

Could someone please suggest how should I approach this problem? ( if we have any solution without using aggregation )

4
  • You can get the result by using the $ projection operator. Commented May 18, 2020 at 10:40
  • @prasad_ - 1. projection can not be used on multi level nested array. 2. problem is mainly to find if an element type=conv exists for given d --> ds--> rs , it is finding it based on filter i am using , since type is present another d-->ds Commented May 18, 2020 at 10:45
  • "1. projection can not be used on multi level nested array." It can be used. Commented May 18, 2020 at 10:46
  • Can you pls provide me an example, of filter based on above, i can try to confirm to be aligned with you? Commented May 18, 2020 at 10:47

2 Answers 2

2

You need to use $elemMatch for these type of condition, And you can match strings without $eq operator

filter = {"$and": [
    {"c_name": "c1"},
    {"t_name": "t1"},
    { "d": { $elemMatch: { "name": "d2", "ds.name": "ds2" , "ds.rs.type": "conv"} } }
]}

With $elemMatch It will search only in the array where all condition will be true

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

Comments

0

Thanks @puneet , i need to try above. However, i am using now this

filter_query = {
                "$and": [
                    {"c_name": {'$eq': 'c1'}},
                    {"t_name": {'$eq': 't1'}},
                    {
                        'd': {
                            '$elemMatch': {
                                'name': 'd2',
                                'ds': {
                                    '$elemMatch':
                                        {'name': 'ds2',
                                         'rs':
                                             {'$elemMatch':
                                                 {
                                                     "type": 'conv'}
                                             }
                                         }
                                }
                            }
                        }
                    }]}

This is also working !!

3 Comments

Nice, you are checking the condition on every lever, Yes it depends on requirement :)
Happy to help :)
Thanks, indeed, array element is not unique, can be located across different array indices.

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.