我将以下数据的数据结构存储在MongoDB集合中。
其中一个数据条目如下所示:
{
"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": []
}
}
]
}
}
我的问题是:如何检索拓扑,对于任何两个节点之间的所有连接,其网络都具有networkQuality.name ='3G'。
这是我的主意,但是由于我对MongoDB的了解还不是很丰富,所以我不知道如何将其表达为有效的查询。
有人知道怎么做吗?
答案 0 :(得分:1)
不幸的是,我无法仅使用单个查询来解决此问题,但是我发现了两个查询,并在它们之间进行了简单的“ JavaScript处理”。
第一个更改是,我没有在同一集合中存储带有嵌入式节点的拓扑,但是我有一个集合用于我的拓扑,另一个集合用于节点。
拓扑收集结构很简单:
{
"caption": "small-i=1-net=3G"
"id": 0
"specification": "tosca"
"specificationLang": "tosca"
"structure_root_node_id": 0
}
我决定将Node结构存储为带有子引用的树。正是mongodb docu建议使用here。
表示代表节点的文档的存储方式如下:
{
"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
}
这是我寻求解决方案的方法:
1。检索属于同一拓扑的所有节点的ID:
我将拓扑结构与根节点结合在一起,然后使用图形查找来获取属于同一拓扑结构的所有节点。
[{$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
}}]
通过运行上述管道,我获得了一个包含拓扑所有节点ID的数组。
{
"_id" : ObjectId("5c5af8c6dfe2bc05bfc6ed0b"),
"endpoints" :
[
{ "id" : 4 },
{ "id" : 1 },
{ "id" : 0 },
{ "id" : 2 },
{ "id" : 3 }
]
}
2。这是JS处理步骤,在这里,我必须从端点数组中提取id为以下形式:[4、1、0、2、3] (如果我可以将其作为其中一部分的话,那就太好了。管道,但不知道是否可能。)
3。执行查找
{
$and: [
{ connections: { $elemMatch: { 'networkQuality.name': { $nin: ['3G'] } } } },
{ id: { $in: [0, 1, 2, 3, 4] } }
]
}
这将返回任何具有至少一个不同于“ 3G”的连接的节点,这意味着如果查询未返回任何内容,则我发现拓扑具有两个具有网络质量的任何节点之间的所有连接。name='3G'。
只需一个查询即可解决所有问题,但这是我目前发现的唯一解决方案。 (注意:我不想在拓扑字段中存储所有拓扑的节点ID)