Как объединить результаты и переформатировать в MongoDB - PullRequest
1 голос
/ 19 октября 2019

У меня есть такие документы:

{
    "si" : "10.131.6.79",
    "sp" : 36158,
    "n" : "snat",
    "tsi" : "194.230.159.203",
    "tsp" : 36158,
    "di" : "205.185.208.165",
    "dp" : 443
}
{
    "si" : "10.128.103.115",
    "sp" : 56261,
    "n" : "dnat",
    "tdi" : "194.230.159.107",
    "tdp" : 56261,
    "di" : "8.253.207.243",
    "dp" : 443
}

И мне нравится запрашивать, который объединяет результаты нескольких совпадений. Желаемый результат:

{
    "sourceIp" : "10.131.6.79",
    "sourcePort" : 36158,
    "trandisp" : "snat",
    "sourceNatIp" : "194.230.159.203",
    "sourceNatPort" : 36158,
    "destIp" : "205.185.208.165",
    "dp" : 443
}
{
    "sourceIp" : "10.128.103.115",
    "sourcePort" : 56261,
    "trandisp" : "dnat",
    "destinationNatIp" : "194.230.159.107",
    "destinationNatPort" : 56261,
    "destIp" : "8.253.207.243",
    "destPort" : 443
}

В принципе, мне это удалось с помощью этой команды:

{ $concatArrays: [ 
db.sessions.aggregate([
    {$match:{n:"snat"}},
    {$project : {
      _id : 0,sourceIp : "$si",sourcePort : "$sp",sourceNatIp : "$tsi",sourceNatPort : "$tsp", destIp : "$di",destPort : "$dp", trandisp: "$n"
    }}
  ]),
db.sessions.aggregate([
    {$match:{n:"dnat"}},
    {$project : {
      _id : 0,sourceIp : "$si",sourcePort : "$sp",destinationNatIp : "$tdi",destinationNatPort : "$tdp", destIp : "$di",destPort : "$dp" ,trandisp: "$n"
    }}
  ])
 ] }

Но мне нужно это как результат запроса, т.е. мне нравится создавать представление.

В SQL я бы написал

select 
    si as SourceIp, sp as SourcePort, n as transdisp, 
    tsi as SourceNatIp, tsp as SouceNatPort, 
    null as DestinationNatIp, null as DestinationNatPort
from sessions
where n = 'snat'
union all
select 
    si as SourceIp, sp as SourcePort, n as transdisp, 
    null as SourceNatIp, null as SouceNatPort, 
    tdi as DestinationNatIp, tdp as DestinationNatPort
from sessions
where n = 'dnat';

1 Ответ

0 голосов
/ 20 октября 2019

Вы можете попытаться взглянуть на оператор $ facet , который позволяет запускать несколько отдельных запросов и получать результаты в виде одного документа. Затем вы можете запустить $ concatArrays , $ unwind и $ replaceRoot для объединения и продвижения результатов вашего запроса.

db.sessions.aggregate([
    {
        $facet: {
            q1: [
                { $match:{n:"snat"} },
                { $project : {
                _id : 0,sourceIp : "$si",sourcePort : "$sp",sourceNatIp : "$tsi",sourceNatPort : "$tsp", destIp : "$di",destPort : "$dp", trandisp: "$n"
                }}
            ],
            q2: [
                { $match:{n:"dnat"}},
                { $project : {
                _id : 0,sourceIp : "$si",sourcePort : "$sp",destinationNatIp : "$tdi",destinationNatPort : "$tdp", destIp : "$di",destPort : "$dp" ,trandisp: "$n"
                }}
            ]
        }
    },
    {
        $project: {
            all: {
                $concatArrays: [ "$q1", "$q2" ]
            }
        }
    },
    {
        $unwind: "$all"
    },
    {
        $replaceRoot: {
            newRoot: "$all"
        }
    }
])

Mongo Playground

...