К сожалению, я не могу решить эту проблему, используя только один запрос, но я нашел два запроса и выполняю простую «обработку JavaScript» между ними.
Первое изменение заключается в том, что я не храню топологиюсо встроенными узлами в той же коллекции, но у меня есть одна коллекция для моих топологий и другая для узлов.
Структура коллекции топологии проста:
{
"caption": "small-i=1-net=3G"
"id": 0
"specification": "tosca"
"specificationLang": "tosca"
"structure_root_node_id": 0
}
И я решил сохранить структуру узлов какдерево с дочерними ссылками.Точно так же, как в документации mongodb здесь .
Означает, что документ, представляющий узел, хранится так:
{
"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.Получить идентификаторы всех узлов, принадлежащих к одной и той же топологии:
Я объединяю топологии с корневыми узлами, а затем использую поиск в графе для получения всех узлов, которые являются частью одной топологии.
[{$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" : ObjectId("5c5af8c6dfe2bc05bfc6ed0b"),
"endpoints" :
[
{ "id" : 4 },
{ "id" : 1 },
{ "id" : 0 },
{ "id" : 2 },
{ "id" : 3 }
]
}
2.Это этап обработки JS, где мне нужно извлечь идентификаторы из массива конечных точек в следующую форму: [4, 1, 0, 2, 3] (было бы хорошо, если бы я мог сделать это как частьтрубопровод, но не знаю, если это возможно).
3.Выполнить поиск
{
$and: [
{ connections: { $elemMatch: { 'networkQuality.name': { $nin: ['3G'] } } } },
{ id: { $in: [0, 1, 2, 3, 4] } }
]
}
Это вернет любой узел, имеющий хотя бы одно соединение, отличное от '3G', означает, что , если запрос ничего не возвращает, я нашел топологию со всеми соединениями между любымидва узла с сетевым качеством. name = '3G'.
Было бы неплохо решить все это одним запросом, но это единственное решение, которое я нашел к настоящему времени.(примечание: я не хочу хранить идентификаторы узлов всех топологий в поле топологии)