Q:

Match fields of association class in a recursive structure

I have the following data structure of my data stored in a MongoDB collection.

One of the data entries looks like the following:
{
    "id": 0,
    ...
    "structure": {
        "id": 0,
        "name": "rsu2",
        "peers": [
            {
                "networkQuality": {
                    "name": "3G",
                    "latency": "200ms",
                    "bandwidth": "1000kbps"
                },
                "connectionEndpoint": {
                    "id": 1,
                    "name": "vehicle1",
                    "peers": []
                }
            },
            {
                "networkQuality": {
                    "name": "3G",
                    "latency": "200ms",
                    "bandwidth": "1000kbps"
                },
                "connectionEndpoint": {
                    "id": 2,
                    "name": "vehicle2",
                    "peers": []
                }
            }
        ]
    }
}

My question is: How can I retrieve the Topologies, which have networkQuality.name = '3G' for all connections between any two Nodes.
This is my idea, but since I am not so experienced in MongoDB yet, I don't know exactly how to formulate it into a working query.

Since it's a recursive structure, I would use a javascript function defined within the $where operator (as done here) to match networkQuality.name='3G' anywhere within the recursive structure.
By the approach described in the previous point, I would retrieve all topologies having at least one networkQuality.name='3G' and topologies having at least one networkQuality.name!='3G'. After doing this I have two sets. When I apply the set minus operation on those (first result - second result), I would obtain the desired result.

Does anyone have an idea how to do this ?

A:

Unfortunately I can't solve this by using just a single query, but I found two queries and do a simple "Javascript  processing" between them.
First change is that I don't store a topology with embedded Nodes in the same collection, but I have one collection for my topologies and another for the nodes.
The topology collection structure is simple: 
{
    "caption": "small-i=1-net=3G"
    "id": 0
    "specification": "tosca"
    "specificationLang": "tosca"
    "structure_root_node_id": 0
}

And I decided to store the Node structure as the tree with child references. Exactly as the mongodb docu suggests here.
Means a document representing a Node is stored like this:
{ 
    "id": 0
    "connections" : [ 
        { 
            "networkQuality" : 
                { 
                    "name" : "3G", 
                    "latency" : "200ms", 
                    "bandwidth" : "1000kbps" 
                }, 
            "endpoint_id" : 1 
        }, 
        { 
            "networkQuality" : 
                { 
                    "name" : "3G", 
                    "latency" : "200ms", 
                    "bandwidth" : "1000kbps"
                }, 
            "endpoint_id" : 2 } 
        ],
    "name" : "edge1", 
    "nodeType" : 1
}

This my approach towards the solution:
1. Retrieve all node's ids belonging to the same topology:
 I join the topologies with root nodes and then I use graph lookup to obtain all nodes, which are part of the same topology.
[{$lookup: {
  from: 'node_structure',
  localField: 'structure_root_node_id',
  foreignField: 'id',
  as: 'structure'
}}, {$graphLookup: {
  from: 'node_structure',
  startWith: '$structure.id',
  connectFromField: 'connections.endpoint_id',
  connectToField: 'id',
  as: 'endpoints'
}}, {$project: {
  "endpoints.id": 1
}}]

By running the above pipeline I obtain an array containing all node ids of my topology.
{ 
    "_id" : ObjectId("5c5af8c6dfe2bc05bfc6ed0b"), 
    "endpoints" : 
        [ 
            { "id" : 4 }, 
            { "id" : 1 }, 
            { "id" : 0 }, 
            { "id" : 2 }, 
            { "id" : 3 } 
        ] 
}

2. This is the JS processing step, where I have to extract ids from endpoints array to a following form: [4, 1, 0, 2, 3] (it would be nice if I could do this as a part of the pipeline, but don't know if possible).
3. Execute the find
{
    $and: [
        { connections: { $elemMatch: { 'networkQuality.name': { $nin: ['3G'] } } } },
        { id: { $in: [0, 1, 2, 3, 4] } }
    ]
}

This will return any Node having at least one connection different than '3G', means that if the query returns nothing I found the topology with all connections between any two nodes having network quality.name = '3G'.
Would be nice to solve it all with just a single query, but this is the only solution I found by now. (note: I don't want to store all topologies' nodes ids in a topology field)

